15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This file implements the SERVER Session ID cache.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOTE:  The contents of this file are NOT used by the client.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This Source Code Form is subject to the terms of the Mozilla Public
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * License, v. 2.0. If a copy of the MPL was not distributed with this
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cache sids!
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * About record locking among different server processes:
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All processes that are part of the same conceptual server (serving on
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the same address and port) MUST share a common SSL session cache.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This code makes the content of the shared cache accessible to all
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * processes on the same "server".  This code works on Unix and Win32 only.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We use NSPR anonymous shared memory and move data to & from shared memory.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We must do explicit locking of the records for all reads and writes.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The set of Cache entries are divided up into "sets" of 128 entries.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Each set is protected by a lock.  There may be one or more sets protected
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * by each lock.  That is, locks to sets are 1:N.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * There is one lock for the entire cert cache.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * There is one lock for the set of wrapped sym wrap keys.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The anonymous shared memory is laid out as if it were declared like this:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * struct {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     cacheDescriptor          desc;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     sidCacheLock             sidCacheLocks[ numSIDCacheLocks];
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     sidCacheLock             keyCacheLock;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     sidCacheLock             certCacheLock;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     sidCacheSet              sidCacheSets[ numSIDCacheSets ];
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     sidCacheEntry            sidCacheData[ numSIDCacheEntries];
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     certCacheEntry           certCacheData[numCertCacheEntries];
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     SSLWrappedSymWrappingKey keyCacheData[kt_kea_size][SSL_NUM_WRAP_MECHS];
37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *     PRUint8                  keyNameSuffix[SESS_TICKET_KEY_VAR_NAME_LEN]
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     encKeyCacheEntry         ticketEncKey; // Wrapped in non-bypass mode
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     encKeyCacheEntry         ticketMacKey; // Wrapped in non-bypass mode
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     PRBool                   ticketKeysValid;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     sidCacheLock             srvNameCacheLock;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     srvNameCacheEntry        srvNameData[ numSrvNameCacheEntries ];
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * } cacheMemCacheData;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "seccomon.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "cert.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ssl.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslimpl.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslproto.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pk11func.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base64.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "keyhi.h"
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "blapit.h"
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sechash.h"
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "blapi.h"
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(XP_UNIX) || defined(XP_BEOS)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <syslog.h>
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h>
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h>
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <signal.h>
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "unix_err.h"
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef XP_WIN32
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <wtypes.h>
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win32err.h"
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SET_ERROR_CODE /* reminder */
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nspr.h"
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslmutex.h"
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Format of a cache entry in the shared memory.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct sidCacheEntryStr {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 16 */    PRIPv6Addr  addr;	/* client's IP address */
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  4 */    PRUint32    creationTime;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  4 */    PRUint32    lastAccessTime;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  4 */    PRUint32    expirationTime;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  2 */    PRUint16	version;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  1 */    PRUint8	valid;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  1 */    PRUint8     sessionIDLength;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 32 */    PRUint8     sessionID[SSL3_SESSIONID_BYTES];
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  2 */    PRUint16    authAlgorithm;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  2 */    PRUint16    authKeyBits;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  2 */    PRUint16    keaType;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  2 */    PRUint16    keaKeyBits;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 72  - common header total */
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    union {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 64 */    PRUint8	masterKey[SSL_MAX_MASTER_KEY_BYTES];
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 32 */    PRUint8	cipherArg[SSL_MAX_CYPHER_ARG_BYTES];
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  1 */    PRUint8	cipherType;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  1 */    PRUint8	masterKeyLen;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  1 */    PRUint8	keyBits;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  1 */    PRUint8	secretKeyBits;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  1 */    PRUint8	cipherArgLen;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*101 */} ssl2;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  2 */    ssl3CipherSuite  cipherSuite;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  2 */    PRUint16    compression; 	/* SSLCompressionMethod */
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* 52 */    ssl3SidKeys keys;	/* keys, wrapped as needed. */
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  4 */    PRUint32    masterWrapMech;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  4 */    SSL3KEAType exchKeyType;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  4 */    PRInt32     certIndex;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  4 */    PRInt32     srvNameIndex;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 32 */    PRUint8     srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*104 */} ssl3;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* force sizeof(sidCacheEntry) to be a multiple of cache line size */
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        struct {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*120 */    PRUint8     filler[120]; /* 72+120==192, a multiple of 16 */
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} forceSize;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } u;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct sidCacheEntryStr sidCacheEntry;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The length of this struct is supposed to be a power of 2, e.g. 4KB */
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct certCacheEntryStr {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint16    certLength;				/*    2 */
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint16    sessionIDLength;			/*    2 */
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint8 	sessionID[SSL3_SESSIONID_BYTES];	/*   32 */
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint8 	cert[SSL_MAX_CACHED_CERT_LEN];		/* 4060 */
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};						/* total   4096 */
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct certCacheEntryStr certCacheEntry;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct sidCacheLockStr {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32	timeStamp;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslMutex	mutex;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslPID	pid;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct sidCacheLockStr sidCacheLock;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct sidCacheSetStr {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRIntn	next;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct sidCacheSetStr sidCacheSet;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct encKeyCacheEntryStr {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint8	bytes[512];
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32	length;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct encKeyCacheEntryStr encKeyCacheEntry;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SSL_MAX_DNS_HOST_NAME  1024
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct srvNameCacheEntryStr {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint16    type;                                   /*    2 */
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint16    nameLen;                                /*    2 */
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint8	name[SSL_MAX_DNS_HOST_NAME + 12];       /* 1034 */
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint8 	nameHash[SHA256_LENGTH];                /*   32 */
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        /* 1072 */
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct srvNameCacheEntryStr srvNameCacheEntry;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct cacheDescStr {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32            cacheMemSize;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32		numSIDCacheLocks;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32		numSIDCacheSets;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32		numSIDCacheSetsPerLock;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32            numSIDCacheEntries;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32            sidCacheSize;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32            numCertCacheEntries;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32            certCacheSize;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32            numKeyCacheEntries;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32            keyCacheSize;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32            numSrvNameCacheEntries;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32            srvNameCacheSize;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32		ssl2Timeout;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32		ssl3Timeout;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32            numSIDCacheLocksInitialized;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* These values are volatile, and are accessed through sharedCache-> */
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32		nextCertCacheEntry;	/* certCacheLock protects */
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool      	stopPolling;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool		everInherited;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* The private copies of these values are pointers into shared mem */
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* The copies of these values in shared memory are merely offsets */
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheLock    *          sidCacheLocks;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheLock    *          keyCacheLock;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheLock    *          certCacheLock;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheLock    *          srvNameCacheLock;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheSet     *          sidCacheSets;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheEntry   *          sidCacheData;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    certCacheEntry  *          certCacheData;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLWrappedSymWrappingKey * keyCacheData;
218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8         *          ticketKeyNameSuffix;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encKeyCacheEntry         * ticketEncKey;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encKeyCacheEntry         * ticketMacKey;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32        *          ticketKeysValid;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    srvNameCacheEntry *        srvNameCacheData;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Only the private copies of these pointers are valid */
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *                     cacheMem;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct cacheDescStr *      sharedCache;  /* shared copy of this struct */
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileMap *                cacheMemMap;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRThread  *                poller;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32                   mutexTimeout;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool                     shared;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct cacheDescStr cacheDesc;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static cacheDesc globalCache;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char envVarName[] = { SSL_ENV_VAR_NAME };
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool isMultiProcess  = PR_FALSE;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEF_SID_CACHE_ENTRIES  10000
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEF_CERT_CACHE_ENTRIES 250
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MIN_CERT_CACHE_ENTRIES 125 /* the effective size in old releases. */
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEF_KEY_CACHE_ENTRIES  250
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEF_NAME_CACHE_ENTRIES  1000
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SID_CACHE_ENTRIES_PER_SET  128
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SID_ALIGNMENT          16
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEF_SSL2_TIMEOUT	100   /* seconds */
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_SSL2_TIMEOUT	100   /* seconds */
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MIN_SSL2_TIMEOUT	  5   /* seconds */
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEF_SSL3_TIMEOUT      86400L  /* 24 hours */
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_SSL3_TIMEOUT      86400L  /* 24 hours */
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MIN_SSL3_TIMEOUT          5   /* seconds  */
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(AIX) || defined(LINUX) || defined(NETBSD) || defined(OPENBSD)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_SID_CACHE_LOCKS 8	/* two FDs per lock */
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OSF1)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_SID_CACHE_LOCKS 16	/* one FD per lock */
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_SID_CACHE_LOCKS 256
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SID_HOWMANY(val, size) (((val) + ((size) - 1)) / (size))
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SID_ROUNDUP(val, size) ((size) * SID_HOWMANY((val), (size)))
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslPID myPid;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRUint32  ssl_max_sid_cache_locks = MAX_SID_CACHE_LOCKS;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* forward static function declarations */
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRUint32 SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         unsigned nl);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus LaunchLockPoller(cacheDesc *cache);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus StopLockPoller(cacheDesc *cache);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct inheritanceStr {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 cacheMemSize;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 fmStrLen;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct inheritanceStr inheritance;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_WIN32) || defined(XP_OS2)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEFAULT_CACHE_DIRECTORY "\\temp"
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* _win32 */
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(XP_UNIX) || defined(XP_BEOS)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEFAULT_CACHE_DIRECTORY "/tmp"
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* XP_UNIX || XP_BEOS */
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************/
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRUint32
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LockSidCacheLock(sidCacheLock *lock, PRUint32 now)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus      rv      = sslMutex_Lock(&lock->mutex);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return 0;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!now)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	now  = ssl_Time();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lock->timeStamp = now;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lock->pid       = myPid;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return now;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UnlockSidCacheLock(sidCacheLock *lock)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus      rv;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lock->pid = 0;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv        = sslMutex_Unlock(&lock->mutex);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* returns the value of ssl_Time on success, zero on failure. */
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRUint32
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LockSet(cacheDesc *cache, PRUint32 set, PRUint32 now)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32       lockNum = set % cache->numSIDCacheLocks;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheLock * lock    = cache->sidCacheLocks + lockNum;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LockSidCacheLock(lock, now);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UnlockSet(cacheDesc *cache, PRUint32 set)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32       lockNum = set % cache->numSIDCacheLocks;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheLock * lock    = cache->sidCacheLocks + lockNum;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return UnlockSidCacheLock(lock);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************/
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Put a certificate in the cache.  Update the cert index in the sce.
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRUint32
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CacheCert(cacheDesc * cache, CERTCertificate *cert, sidCacheEntry *sce)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32        now;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    certCacheEntry  cce;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((cert->derCert.len > SSL_MAX_CACHED_CERT_LEN) ||
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (cert->derCert.len <= 0) ||
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cert->derCert.data == NULL)) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cce.sessionIDLength = sce->sessionIDLength;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(cce.sessionID, sce->sessionID, cce.sessionIDLength);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cce.certLength = cert->derCert.len;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(cce.cert, cert->derCert.data, cce.certLength);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* get lock on cert cache */
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = LockSidCacheLock(cache->certCacheLock, 0);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (now) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Find where to place the next cert cache entry. */
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cacheDesc * sharedCache = cache->sharedCache;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint32    ndx         = sharedCache->nextCertCacheEntry;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* write the entry */
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cache->certCacheData[ndx] = cce;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* remember where we put it. */
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sce->u.ssl3.certIndex = ndx;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* update the "next" cache entry index */
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sharedCache->nextCertCacheEntry =
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					(ndx + 1) % cache->numCertCacheEntries;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	UnlockSidCacheLock(cache->certCacheLock);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return now;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Server configuration hash tables need to account the SECITEM.type
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * field as well. These functions accomplish that. */
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PLHashNumber
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Get32BitNameHash(const SECItem *name)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PLHashNumber rv = SECITEM_Hash(name);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint8 *rvc = (PRUint8 *)&rv;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rvc[ name->len % sizeof(rv) ] ^= name->type;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Put a name in the cache.  Update the cert index in the sce.
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRUint32
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CacheSrvName(cacheDesc * cache, SECItem *name, sidCacheEntry *sce)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32           now;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32           ndx;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    srvNameCacheEntry  snce;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!name || name->len <= 0 ||
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name->len > SSL_MAX_DNS_HOST_NAME) {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    snce.type = name->type;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    snce.nameLen = name->len;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(snce.name, name->data, snce.nameLen);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HASH_HashBuf(HASH_AlgSHA256, snce.nameHash, name->data, name->len);
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SHA256_HashBuf(snce.nameHash, (unsigned char*)name->data,
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   name->len);
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* get index of the next name */
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ndx = Get32BitNameHash(name);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* get lock on cert cache */
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = LockSidCacheLock(cache->srvNameCacheLock, 0);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (now) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (cache->numSrvNameCacheEntries > 0) {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* Fit the index into array */
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ndx %= cache->numSrvNameCacheEntries;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* write the entry */
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cache->srvNameCacheData[ndx] = snce;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* remember where we put it. */
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sce->u.ssl3.srvNameIndex = ndx;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* Copy hash into sid hash */
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PORT_Memcpy(sce->u.ssl3.srvNameHash, snce.nameHash, SHA256_LENGTH);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	UnlockSidCacheLock(cache->srvNameCacheLock);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return now;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Convert local SID to shared memory one
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConvertFromSID(sidCacheEntry *to, sslSessionID *from)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->valid   = 1;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->version = from->version;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->addr    = from->addr;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->creationTime    = from->creationTime;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->lastAccessTime  = from->lastAccessTime;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->expirationTime  = from->expirationTime;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->authAlgorithm	= from->authAlgorithm;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->authKeyBits	= from->authKeyBits;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->keaType		= from->keaType;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->keaKeyBits	= from->keaKeyBits;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (from->version < SSL_LIBRARY_VERSION_3_0) {
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((from->u.ssl2.masterKey.len > SSL_MAX_MASTER_KEY_BYTES) ||
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (from->u.ssl2.cipherArg.len > SSL_MAX_CYPHER_ARG_BYTES)) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL: masterKeyLen=%d cipherArgLen=%d",
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     myPid, from->u.ssl2.masterKey.len,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     from->u.ssl2.cipherArg.len));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    to->valid = 0;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.cipherType    = from->u.ssl2.cipherType;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.masterKeyLen  = from->u.ssl2.masterKey.len;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.cipherArgLen  = from->u.ssl2.cipherArg.len;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.keyBits       = from->u.ssl2.keyBits;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->sessionIDLength      = SSL2_SESSIONID_BYTES;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(to->sessionID, from->u.ssl2.sessionID, SSL2_SESSIONID_BYTES);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(to->u.ssl2.masterKey, from->u.ssl2.masterKey.data,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  from->u.ssl2.masterKey.len);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(to->u.ssl2.cipherArg, from->u.ssl2.cipherArg.data,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  from->u.ssl2.cipherArg.len);
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memset(to->u.ssl2.masterKey+from->u.ssl2.masterKey.len, 0,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  sizeof(to->u.ssl2.masterKey) - from->u.ssl2.masterKey.len);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memset(to->u.ssl2.cipherArg+from->u.ssl2.cipherArg.len, 0,
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  sizeof(to->u.ssl2.cipherArg) - from->u.ssl2.cipherArg.len);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_TRC(8, ("%d: SSL: ConvertSID: masterKeyLen=%d cipherArgLen=%d "
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "time=%d addr=0x%08x%08x%08x%08x cipherType=%d", myPid,
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->u.ssl2.masterKeyLen, to->u.ssl2.cipherArgLen,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->creationTime, to->addr.pr_s6_addr32[0],
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2],
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->addr.pr_s6_addr32[3], to->u.ssl2.cipherType));
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* This is an SSL v3 session */
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.cipherSuite      = from->u.ssl3.cipherSuite;
503a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	to->u.ssl3.compression      = (PRUint16)from->u.ssl3.compression;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.keys             = from->u.ssl3.keys;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.masterWrapMech   = from->u.ssl3.masterWrapMech;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.exchKeyType      = from->u.ssl3.exchKeyType;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->sessionIDLength         = from->u.ssl3.sessionIDLength;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.certIndex        = -1;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.srvNameIndex     = -1;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->sessionIDLength);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x "
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	            "cipherSuite=%d",
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    myPid, to->creationTime, to->addr.pr_s6_addr32[0],
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2],
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->addr.pr_s6_addr32[3], to->u.ssl3.cipherSuite));
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Convert shared memory cache-entry to local memory based one
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This is only called from ServerSessionIDLookup().
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Caller must hold cache lock when calling this.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslSessionID *
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConvertToSID(sidCacheEntry *    from,
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             certCacheEntry *   pcce,
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             srvNameCacheEntry *psnce,
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             CERTCertDBHandle * dbHandle)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSessionID *to;
534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint16 version = from->version;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    to = PORT_ZNew(sslSessionID);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!to) {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (version < SSL_LIBRARY_VERSION_3_0) {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* This is an SSL v2 session */
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.masterKey.data =
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (unsigned char*) PORT_Alloc(from->u.ssl2.masterKeyLen);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!to->u.ssl2.masterKey.data) {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (from->u.ssl2.cipherArgLen) {
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    to->u.ssl2.cipherArg.data =
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	(unsigned char*)PORT_Alloc(from->u.ssl2.cipherArgLen);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!to->u.ssl2.cipherArg.data) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto loser;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Memcpy(to->u.ssl2.cipherArg.data, from->u.ssl2.cipherArg,
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        from->u.ssl2.cipherArgLen);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.cipherType    = from->u.ssl2.cipherType;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.masterKey.len = from->u.ssl2.masterKeyLen;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.cipherArg.len = from->u.ssl2.cipherArgLen;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.keyBits       = from->u.ssl2.keyBits;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*	to->sessionIDLength      = SSL2_SESSIONID_BYTES; */
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(to->u.ssl2.sessionID, from->sessionID, SSL2_SESSIONID_BYTES);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(to->u.ssl2.masterKey.data, from->u.ssl2.masterKey,
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    from->u.ssl2.masterKeyLen);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_TRC(8, ("%d: SSL: ConvertToSID: masterKeyLen=%d cipherArgLen=%d "
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "time=%d addr=0x%08x%08x%08x%08x cipherType=%d",
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    myPid, to->u.ssl2.masterKey.len,
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->u.ssl2.cipherArg.len, to->creationTime,
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->addr.pr_s6_addr32[0], to->addr.pr_s6_addr32[1],
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->addr.pr_s6_addr32[2], to->addr.pr_s6_addr32[3],
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    to->u.ssl2.cipherType));
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* This is an SSL v3 session */
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.sessionIDLength  = from->sessionIDLength;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.cipherSuite      = from->u.ssl3.cipherSuite;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.compression      = (SSLCompressionMethod)from->u.ssl3.compression;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.keys             = from->u.ssl3.keys;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.masterWrapMech   = from->u.ssl3.masterWrapMech;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.exchKeyType      = from->u.ssl3.exchKeyType;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (from->u.ssl3.srvNameIndex != -1 && psnce) {
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SECItem name;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SECStatus rv;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            name.type                   = psnce->type;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            name.len                    = psnce->nameLen;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            name.data                   = psnce->name;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = SECITEM_CopyItem(NULL, &to->u.ssl3.srvName, &name);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) {
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                goto loser;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(to->u.ssl3.sessionID, from->sessionID, from->sessionIDLength);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* the portions of the SID that are only restored on the client
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * are set to invalid values on the server.
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.clientWriteKey   = NULL;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.serverWriteKey   = NULL;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->urlSvrName              = NULL;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.masterModuleID   = (SECMODModuleID)-1; /* invalid value */
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.masterSlotID     = (CK_SLOT_ID)-1;     /* invalid value */
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.masterWrapIndex  = 0;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.masterWrapSeries = 0;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.masterValid      = PR_FALSE;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.clAuthModuleID   = (SECMODModuleID)-1; /* invalid value */
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.clAuthSlotID     = (CK_SLOT_ID)-1;     /* invalid value */
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.clAuthSeries     = 0;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to->u.ssl3.clAuthValid      = PR_FALSE;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (from->u.ssl3.certIndex != -1 && pcce) {
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SECItem          derCert;
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    derCert.len  = pcce->certLength;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    derCert.data = pcce->cert;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    to->peerCert = CERT_NewTempCertificate(dbHandle, &derCert, NULL,
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					           PR_FALSE, PR_TRUE);
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (to->peerCert == NULL)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto loser;
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->version         = from->version;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->creationTime    = from->creationTime;
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->lastAccessTime  = from->lastAccessTime;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->expirationTime  = from->expirationTime;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->cached          = in_server_cache;
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->addr            = from->addr;
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->references      = 1;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->authAlgorithm	= from->authAlgorithm;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->authKeyBits	= from->authKeyBits;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->keaType		= from->keaType;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->keaKeyBits	= from->keaKeyBits;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return to;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  loser:
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to) {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (version < SSL_LIBRARY_VERSION_3_0) {
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (to->u.ssl2.masterKey.data)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_Free(to->u.ssl2.masterKey.data);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (to->u.ssl2.cipherArg.data)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_Free(to->u.ssl2.cipherArg.data);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SECITEM_FreeItem(&to->u.ssl3.srvName, PR_FALSE);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Free(to);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Perform some mumbo jumbo on the ip-address and the session-id value to
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** compute a hash value.
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRUint32
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, unsigned nl)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 rv;
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 x[8];
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(x, 0, sizeof x);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nl > sizeof x)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	nl = sizeof x;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(x, s, nl);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = (addr->pr_s6_addr32[0] ^ addr->pr_s6_addr32[1] ^
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  addr->pr_s6_addr32[2] ^ addr->pr_s6_addr32[3] ^
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          x[0] ^ x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7])
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  % cache->numSIDCacheSets;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Look something up in the cache. This will invalidate old entries
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in the process. Caller has locked the cache set!
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Returns PR_TRUE if found a valid match.  PR_FALSE otherwise.
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sidCacheEntry *
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindSID(cacheDesc *cache, PRUint32 setNum, PRUint32 now,
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const PRIPv6Addr *addr, unsigned char *sessionID,
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned sessionIDLength)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32      ndx   = cache->sidCacheSets[setNum].next;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int           i;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheEntry * set = cache->sidCacheData +
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    			 (setNum * SID_CACHE_ENTRIES_PER_SET);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = SID_CACHE_ENTRIES_PER_SET; i > 0; --i) {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sidCacheEntry * sce;
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ndx  = (ndx - 1) % SID_CACHE_ENTRIES_PER_SET;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sce = set + ndx;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!sce->valid)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (now > sce->expirationTime) {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* SessionID has timed out. Invalidate the entry. */
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRC(7, ("%d: timed out sid entry addr=%08x%08x%08x%08x now=%x "
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"time+=%x",
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			myPid, sce->addr.pr_s6_addr32[0],
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sce->addr.pr_s6_addr32[1], sce->addr.pr_s6_addr32[2],
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sce->addr.pr_s6_addr32[3], now,
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sce->expirationTime ));
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sce->valid = 0;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	** Next, examine specific session-id/addr data to see if the cache
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	** entry matches our addr+session-id value
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*/
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sessionIDLength == sce->sessionIDLength      &&
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    !memcmp(&sce->addr, addr, sizeof(PRIPv6Addr)) &&
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    !memcmp(sce->sessionID, sessionID, sessionIDLength)) {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Found it */
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return sce;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND);
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************/
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This is the primary function for finding entries in the server's sid cache.
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Although it is static, this function is called via the global function
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pointer ssl_sid_lookup.
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslSessionID *
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServerSessionIDLookup(const PRIPv6Addr *addr,
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned char *sessionID,
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int   sessionIDLength,
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        CERTCertDBHandle * dbHandle)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSessionID *  sid      = 0;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheEntry * psce;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    certCacheEntry *pcce     = 0;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    srvNameCacheEntry *psnce = 0;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *     cache    = &globalCache;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32        now;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32        set;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32         cndx;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheEntry   sce;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    certCacheEntry  cce;
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    srvNameCacheEntry snce;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set = SIDindex(cache, addr, sessionID, sessionIDLength);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = LockSet(cache, set, 0);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!now)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return NULL;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    psce = FindSID(cache, set, now, addr, sessionID, sessionIDLength);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (psce) {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (psce->version >= SSL_LIBRARY_VERSION_3_0) {
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((cndx = psce->u.ssl3.certIndex) != -1) {
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                PRUint32 gotLock = LockSidCacheLock(cache->certCacheLock, now);
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (gotLock) {
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    pcce = &cache->certCacheData[cndx];
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /* See if the cert's session ID matches the sce cache. */
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if ((pcce->sessionIDLength == psce->sessionIDLength) &&
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        !PORT_Memcmp(pcce->sessionID, psce->sessionID,
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     pcce->sessionIDLength)) {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        cce = *pcce;
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    } else {
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /* The cert doesen't match the SID cache entry,
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ** so invalidate the SID cache entry.
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        psce->valid = 0;
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        psce = 0;
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        pcce = 0;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    UnlockSidCacheLock(cache->certCacheLock);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } else {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /* what the ??.  Didn't get the cert cache lock.
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ** Don't invalidate the SID cache entry, but don't find it.
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    */
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PORT_Assert(!("Didn't get cert Cache Lock!"));
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    psce = 0;
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    pcce = 0;
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (psce && ((cndx = psce->u.ssl3.srvNameIndex) != -1)) {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                PRUint32 gotLock = LockSidCacheLock(cache->srvNameCacheLock,
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    now);
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (gotLock) {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    psnce = &cache->srvNameCacheData[cndx];
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (!PORT_Memcmp(psnce->nameHash, psce->u.ssl3.srvNameHash,
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     SHA256_LENGTH)) {
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        snce = *psnce;
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    } else {
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /* The name doesen't match the SID cache entry,
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ** so invalidate the SID cache entry.
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        psce->valid = 0;
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        psce = 0;
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        psnce = 0;
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    UnlockSidCacheLock(cache->srvNameCacheLock);
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } else {
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /* what the ??.  Didn't get the cert cache lock.
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ** Don't invalidate the SID cache entry, but don't find it.
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    */
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PORT_Assert(!("Didn't get name Cache Lock!"));
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    psce = 0;
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    psnce = 0;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (psce) {
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    psce->lastAccessTime = now;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sce = *psce;	/* grab a copy while holding the lock */
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	}
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UnlockSet(cache, set);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (psce) {
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* sce conains a copy of the cache entry.
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	** Convert shared memory format to local format
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*/
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sid = ConvertToSID(&sce, pcce ? &cce : 0, psnce ? &snce : 0, dbHandle);
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sid;
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Place a sid into the cache, if it isn't already there.
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServerSessionIDCache(sslSessionID *sid)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheEntry sce;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32      now     = 0;
851a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint16      version = sid->version;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *   cache   = &globalCache;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((version >= SSL_LIBRARY_VERSION_3_0) &&
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(sid->u.ssl3.sessionIDLength == 0)) {
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sid->cached == never_cached || sid->cached == invalid_cache) {
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint32 set;
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(sid->creationTime != 0);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!sid->creationTime)
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->lastAccessTime = sid->creationTime = ssl_Time();
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (version < SSL_LIBRARY_VERSION_3_0) {
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* override caller's expiration time, which uses client timeout
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * duration, not server timeout duration.
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->expirationTime = sid->creationTime + cache->ssl2Timeout;
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x "
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"cipher=%d", myPid, sid->cached,
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sid->creationTime, sid->u.ssl2.cipherType));
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PRINT_BUF(8, (0, "sessionID:", sid->u.ssl2.sessionID,
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  SSL2_SESSIONID_BYTES));
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data,
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  sid->u.ssl2.masterKey.len));
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data,
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  sid->u.ssl2.cipherArg.len));
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* override caller's expiration time, which uses client timeout
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * duration, not server timeout duration.
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->expirationTime = sid->creationTime + cache->ssl3Timeout;
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x "
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"cipherSuite=%d", myPid, sid->cached,
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sid->creationTime, sid->u.ssl3.cipherSuite));
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID,
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  sid->u.ssl3.sessionIDLength));
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ConvertFromSID(&sce, sid);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (version >= SSL_LIBRARY_VERSION_3_0) {
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SECItem *name = &sid->u.ssl3.srvName;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (name->len && name->data) {
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                now = CacheSrvName(cache, name, &sce);
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (sid->peerCert != NULL) {
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                now = CacheCert(cache, sid->peerCert, &sce);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	set = SIDindex(cache, &sce.addr, sce.sessionID, sce.sessionIDLength);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	now = LockSet(cache, set, now);
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (now) {
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PRUint32  next = cache->sidCacheSets[set].next;
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PRUint32  ndx  = set * SID_CACHE_ENTRIES_PER_SET + next;
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Write out new cache entry */
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cache->sidCacheData[ndx] = sce;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cache->sidCacheSets[set].next =
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    				(next + 1) % SID_CACHE_ENTRIES_PER_SET;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    UnlockSet(cache, set);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->cached = in_server_cache;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Although this is static, it is called from ssl via global function pointer
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**	ssl_sid_uncache.  This invalidates the referenced cache entry.
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServerSessionIDUncache(sslSessionID *sid)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *    cache   = &globalCache;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint8 *      sessionID;
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int   sessionIDLength;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRErrorCode    err;
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32       set;
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32       now;
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheEntry *psce;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sid == NULL)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return;
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Uncaching a SID should never change the error code.
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** So save it here and restore it before exiting.
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    err = PR_GetError();
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sessionID       = sid->u.ssl2.sessionID;
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sessionIDLength = SSL2_SESSIONID_BYTES;
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_TRC(8, ("%d: SSL: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x "
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "cipher=%d", myPid, sid->cached,
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sid->creationTime, sid->u.ssl2.cipherType));
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength));
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data,
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      sid->u.ssl2.masterKey.len));
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data,
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      sid->u.ssl2.cipherArg.len));
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sessionID       = sid->u.ssl3.sessionID;
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sessionIDLength = sid->u.ssl3.sessionIDLength;
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_TRC(8, ("%d: SSL3: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x "
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "cipherSuite=%d", myPid, sid->cached,
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sid->creationTime, sid->u.ssl3.cipherSuite));
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength));
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set = SIDindex(cache, &sid->addr, sessionID, sessionIDLength);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = LockSet(cache, set, 0);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (now) {
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	psce = FindSID(cache, set, now, &sid->addr, sessionID, sessionIDLength);
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (psce) {
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    psce->valid = 0;
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	UnlockSet(cache, set);
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sid->cached = invalid_cache;
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_SetError(err);
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef XP_OS2
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INCL_DOSPROCESS
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <os2.h>
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)long gettid(void)
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PTIB ptib;
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PPIB ppib;
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DosGetInfoBlocks(&ptib, &ppib);
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ((long)ptib->tib_ordinal); /* thread id */
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloseCache(cacheDesc *cache)
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int locks_initialized = cache->numSIDCacheLocksInitialized;
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cache->cacheMem) {
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cache->sharedCache) {
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sidCacheLock *pLock = cache->sidCacheLocks;
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (; locks_initialized > 0; --locks_initialized, ++pLock ) {
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* If everInherited is true, this shared cache was (and may
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		** still be) in use by multiple processes.  We do not wish to
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		** destroy the mutexes while they are still in use, but we do
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		** want to free mutex resources associated with this process.
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*/
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sslMutex_Destroy(&pLock->mutex,
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 cache->sharedCache->everInherited);
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cache->shared) {
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PR_MemUnmap(cache->cacheMem, cache->cacheMemSize);
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Free(cache->cacheMem);
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cache->cacheMem = NULL;
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cache->cacheMemMap) {
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PR_CloseFileMap(cache->cacheMemMap);
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cache->cacheMemMap = NULL;
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(cache, 0, sizeof *cache);
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          int maxSrvNameCacheEntries, PRUint32 ssl2_timeout,
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          PRUint32 ssl3_timeout, const char *directory, PRBool shared)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptrdiff_t     ptr;
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheLock *pLock;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *        cacheMem;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileMap *   cacheMemMap;
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *        cfn = NULL;	/* cache file name */
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int           locks_initialized = 0;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int           locks_to_initialize = 0;
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32      init_time;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ( (!cache) || (maxCacheEntries < 0) || (!directory) ) {
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PORT_SetError(SEC_ERROR_INVALID_ARGS);
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECFailure;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cache->cacheMem) {
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Already done */
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECSuccess;
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* make sure loser can clean up properly */
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->shared = shared;
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMem    = cacheMem    = NULL;
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMemMap = cacheMemMap = NULL;
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sharedCache = (cacheDesc *)0;
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numSIDCacheLocksInitialized = 0;
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->nextCertCacheEntry = 0;
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->stopPolling = PR_FALSE;
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->everInherited = PR_FALSE;
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->poller = NULL;
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->mutexTimeout = 0;
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numSIDCacheEntries = maxCacheEntries ? maxCacheEntries
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                : DEF_SID_CACHE_ENTRIES;
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numSIDCacheSets    =
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	SID_HOWMANY(cache->numSIDCacheEntries, SID_CACHE_ENTRIES_PER_SET);
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numSIDCacheEntries =
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	cache->numSIDCacheSets * SID_CACHE_ENTRIES_PER_SET;
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numSIDCacheLocks   =
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PR_MIN(cache->numSIDCacheSets, ssl_max_sid_cache_locks);
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numSIDCacheSetsPerLock =
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	SID_HOWMANY(cache->numSIDCacheSets, cache->numSIDCacheLocks);
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numCertCacheEntries = (maxCertCacheEntries > 0) ?
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             maxCertCacheEntries : 0;
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numSrvNameCacheEntries = (maxSrvNameCacheEntries >= 0) ?
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             maxSrvNameCacheEntries : DEF_NAME_CACHE_ENTRIES;
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* compute size of shared memory, and offsets of all pointers */
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = 0;
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMem     = (char *)ptr;
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr += SID_ROUNDUP(sizeof(cacheDesc), SID_ALIGNMENT);
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sidCacheLocks = (sidCacheLock *)ptr;
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->keyCacheLock  = cache->sidCacheLocks + cache->numSIDCacheLocks;
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->certCacheLock = cache->keyCacheLock  + 1;
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->srvNameCacheLock = cache->certCacheLock  + 1;
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)(cache->srvNameCacheLock + 1);
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sidCacheSets  = (sidCacheSet *)ptr;
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)(cache->sidCacheSets + cache->numSIDCacheSets);
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sidCacheData  = (sidCacheEntry *)ptr;
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)(cache->sidCacheData + cache->numSIDCacheEntries);
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->certCacheData = (certCacheEntry *)ptr;
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sidCacheSize  =
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	(char *)cache->certCacheData - (char *)cache->sidCacheData;
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cache->numCertCacheEntries < MIN_CERT_CACHE_ENTRIES) {
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* This is really a poor way to computer this! */
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cache->numCertCacheEntries = cache->sidCacheSize / sizeof(certCacheEntry);
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (cache->numCertCacheEntries < MIN_CERT_CACHE_ENTRIES)
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	cache->numCertCacheEntries = MIN_CERT_CACHE_ENTRIES;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)(cache->certCacheData + cache->numCertCacheEntries);
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->keyCacheData  = (SSLWrappedSymWrappingKey *)ptr;
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->certCacheSize =
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	(char *)cache->keyCacheData - (char *)cache->certCacheData;
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numKeyCacheEntries = kt_kea_size * SSL_NUM_WRAP_MECHS;
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)(cache->keyCacheData + cache->numKeyCacheEntries);
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->keyCacheSize  = (char *)ptr - (char *)cache->keyCacheData;
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    cache->ticketKeyNameSuffix = (PRUint8 *)ptr;
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)(cache->ticketKeyNameSuffix +
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SESS_TICKET_KEY_VAR_NAME_LEN);
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->ticketEncKey = (encKeyCacheEntry *)ptr;
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)(cache->ticketEncKey + 1);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->ticketMacKey = (encKeyCacheEntry *)ptr;
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)(cache->ticketMacKey + 1);
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->ticketKeysValid = (PRUint32 *)ptr;
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)(cache->ticketKeysValid + 1);
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->srvNameCacheData = (srvNameCacheEntry *)ptr;
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->srvNameCacheSize =
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cache->numSrvNameCacheEntries * sizeof(srvNameCacheEntry);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)(cache->srvNameCacheData + cache->numSrvNameCacheEntries);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMemSize = ptr;
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl2_timeout) {
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ssl2_timeout > MAX_SSL2_TIMEOUT) {
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl2_timeout = MAX_SSL2_TIMEOUT;
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ssl2_timeout < MIN_SSL2_TIMEOUT) {
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl2_timeout = MIN_SSL2_TIMEOUT;
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cache->ssl2Timeout = ssl2_timeout;
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cache->ssl2Timeout = DEF_SSL2_TIMEOUT;
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_timeout) {
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ssl3_timeout > MAX_SSL3_TIMEOUT) {
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl3_timeout = MAX_SSL3_TIMEOUT;
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ssl3_timeout < MIN_SSL3_TIMEOUT) {
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl3_timeout = MIN_SSL3_TIMEOUT;
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cache->ssl3Timeout = ssl3_timeout;
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cache->ssl3Timeout = DEF_SSL3_TIMEOUT;
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (shared) {
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Create file names */
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(XP_UNIX) || defined(XP_BEOS)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* there's some confusion here about whether PR_OpenAnonFileMap wants
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	** a directory name or a file name for its first argument.
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cfn = PR_smprintf("%s/.sslsvrcache.%d", directory, myPid);
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*/
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cfn = PR_smprintf("%s", directory);
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(XP_WIN32)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cfn = PR_smprintf("%s/svrcache_%d_%x.ssl", directory, myPid,
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    GetCurrentThreadId());
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(XP_OS2)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cfn = PR_smprintf("%s/svrcache_%d_%x.ssl", directory, myPid,
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    gettid());
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error "Don't know how to create file name for this platform!"
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!cfn) {
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Create cache */
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cacheMemMap = PR_OpenAnonFileMap(cfn, cache->cacheMemSize,
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					 PR_PROT_READWRITE);
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PR_smprintf_free(cfn);
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if(!cacheMemMap) {
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cacheMem = PR_MemMap(cacheMemMap, 0, cache->cacheMemSize);
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cacheMem = PORT_Alloc(cache->cacheMemSize);
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (! cacheMem) {
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        goto loser;
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Initialize shared memory. This may not be necessary on all platforms */
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(cacheMem, 0, cache->cacheMemSize);
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Copy cache descriptor header into shared memory */
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(cacheMem, cache, sizeof *cache);
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* save private copies of these values */
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMemMap = cacheMemMap;
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMem    = cacheMem;
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sharedCache = (cacheDesc *)cacheMem;
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Fix pointers in our private copy of cache descriptor to point to
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** spaces in shared memory
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)cache->cacheMem;
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->sidCacheLocks) += ptr;
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->keyCacheLock ) += ptr;
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->certCacheLock) += ptr;
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr;
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->sidCacheSets ) += ptr;
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->sidCacheData ) += ptr;
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->certCacheData) += ptr;
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->keyCacheData ) += ptr;
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr;
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->ticketEncKey ) += ptr;
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->ticketMacKey ) += ptr;
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->ticketKeysValid) += ptr;
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->srvNameCacheData) += ptr;
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* initialize the locks */
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    init_time = ssl_Time();
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pLock = cache->sidCacheLocks;
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (locks_to_initialize = cache->numSIDCacheLocks + 3;
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         locks_initialized < locks_to_initialize;
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 ++locks_initialized, ++pLock ) {
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus err = sslMutex_Init(&pLock->mutex, shared);
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (err) {
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cache->numSIDCacheLocksInitialized = locks_initialized;
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pLock->timeStamp = init_time;
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pLock->pid       = 0;
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numSIDCacheLocksInitialized = locks_initialized;
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseCache(cache);
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRUint32
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetMaxServerCacheLocks(void)
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl_max_sid_cache_locks + 2;
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* The extra two are the cert cache lock and the key cache lock. */
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetMaxServerCacheLocks(PRUint32 maxLocks)
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Minimum is 1 sid cache lock, 1 cert cache lock and 1 key cache lock.
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** We'd like to test for a maximum value, but not all platforms' header
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** files provide a symbol or function or other means of determining
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** the maximum, other than trial and error.
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (maxLocks < 3) {
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_max_sid_cache_locks = maxLocks - 2;
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* The extra two are the cert cache lock and the key cache lock. */
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache,
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              PRUint32 ssl2_timeout,
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              PRUint32 ssl3_timeout,
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const char *   directory,
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              PRBool shared,
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              int      maxCacheEntries,
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              int      maxCertCacheEntries,
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              int      maxSrvNameCacheEntries)
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PORT_Assert(sizeof(sidCacheEntry) == 192);
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(sizeof(certCacheEntry) == 4096);
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(sizeof(srvNameCacheEntry) == 1072);
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl_Init();
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) {
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    myPid = SSL_GETPID();
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!directory) {
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	directory = DEFAULT_CACHE_DIRECTORY;
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = InitCache(cache, maxCacheEntries, maxCertCacheEntries,
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   maxSrvNameCacheEntries, ssl2_timeout, ssl3_timeout,
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   directory, shared);
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv) {
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SET_ERROR_CODE
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECFailure;
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_sid_lookup  = ServerSessionIDLookup;
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_sid_cache   = ServerSessionIDCache;
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_sid_uncache = ServerSessionIDUncache;
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ConfigServerSessionIDCacheInstance(	cacheDesc *cache,
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int      maxCacheEntries,
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                PRUint32 ssl2_timeout,
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                PRUint32 ssl3_timeout,
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const char *   directory, PRBool shared)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache,
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         ssl2_timeout,
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         ssl3_timeout,
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         directory,
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         shared,
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         maxCacheEntries,
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         -1, -1);
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ConfigServerSessionIDCache(	int      maxCacheEntries,
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				PRUint32 ssl2_timeout,
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       	PRUint32 ssl3_timeout,
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  const char *   directory)
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
135668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ssl_InitSessionCacheLocks();
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_ConfigServerSessionIDCacheInstance(&globalCache,
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    		maxCacheEntries, ssl2_timeout, ssl3_timeout, directory, PR_FALSE);
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ShutdownServerSessionIDCacheInstance(cacheDesc *cache)
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseCache(cache);
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ShutdownServerSessionIDCache(void)
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(XP_UNIX) || defined(XP_BEOS)
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Stop the thread that polls cache for expired locks on Unix */
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopLockPoller(&globalCache);
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL3_ShutdownServerCache();
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_ShutdownServerSessionIDCacheInstance(&globalCache);
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Use this function, instead of SSL_ConfigServerSessionIDCache,
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if the cache will be shared by multiple processes.
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_ConfigMPServerSIDCacheWithOpt(      PRUint32 ssl2_timeout,
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        PRUint32 ssl3_timeout,
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const char *   directory,
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int maxCacheEntries,
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int maxCertCacheEntries,
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int maxSrvNameCacheEntries)
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *	envValue;
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *	inhValue;
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc * cache         = &globalCache;
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32    fmStrLen;
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus 	result;
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus 	prStatus;
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus	putEnvFailed;
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inheritance inherit;
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char        fmString[PR_FILEMAP_STRING_BUFSIZE];
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    isMultiProcess = PR_TRUE;
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache,
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  ssl2_timeout, ssl3_timeout, directory, PR_TRUE,
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        maxCacheEntries, maxCacheEntries, maxSrvNameCacheEntries);
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result != SECSuccess)
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return result;
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prStatus = PR_ExportFileMapAsString(cache->cacheMemMap,
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        sizeof fmString, fmString);
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((prStatus != PR_SUCCESS) || !(fmStrLen = strlen(fmString))) {
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SET_ERROR_CODE
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inherit.cacheMemSize	= cache->cacheMemSize;
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inherit.fmStrLen            = fmStrLen;
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inhValue = BTOA_DataToAscii((unsigned char *)&inherit, sizeof inherit);
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!inhValue || !strlen(inhValue)) {
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SET_ERROR_CODE
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    envValue = PR_smprintf("%s,%s", inhValue, fmString);
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!envValue || !strlen(envValue)) {
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SET_ERROR_CODE
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Free(inhValue);
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    putEnvFailed = (SECStatus)NSS_PutEnv(envVarName, envValue);
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_smprintf_free(envValue);
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (putEnvFailed) {
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SET_ERROR_CODE
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result = SECFailure;
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(XP_UNIX) || defined(XP_BEOS)
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Launch thread to poll cache for expired locks on Unix */
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LaunchLockPoller(cache);
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Use this function, instead of SSL_ConfigServerSessionIDCache,
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if the cache will be shared by multiple processes.
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ConfigMPServerSIDCache(	int      maxCacheEntries,
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				PRUint32 ssl2_timeout,
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       	PRUint32 ssl3_timeout,
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		          const char *   directory)
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout,
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             ssl3_timeout,
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             directory,
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             maxCacheEntries,
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             -1, -1);
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ConfigServerSessionIDCacheWithOpt(
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				PRUint32 ssl2_timeout,
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       	PRUint32 ssl3_timeout,
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const char *   directory,
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int maxCacheEntries,
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int maxCertCacheEntries,
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int maxSrvNameCacheEntries,
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                PRBool enableMPCache)
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!enableMPCache) {
147068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        ssl_InitSessionCacheLocks();
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache,
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           ssl2_timeout, ssl3_timeout, directory, PR_FALSE,
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries);
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout, ssl3_timeout,
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                directory, maxCacheEntries, maxCertCacheEntries,
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 maxSrvNameCacheEntries);
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char * decoString = NULL;
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *          fmString   = NULL;
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *          myEnvString = NULL;
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int    decoLen;
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptrdiff_t       ptr;
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inheritance     inherit;
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc       my;
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WINNT
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheLock* newLocks;
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int           locks_initialized = 0;
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int           locks_to_initialize = 0;
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus     status = ssl_Init();
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != SECSuccess) {
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return status;
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    myPid = SSL_GETPID();
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* If this child was created by fork(), and not by exec() on unix,
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** then isMultiProcess will already be set.
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** If not, we'll set it below.
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (isMultiProcess) {
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cache && cache->sharedCache) {
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cache->sharedCache->everInherited = PR_TRUE;
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECSuccess;	/* already done. */
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
151568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ssl_InitSessionCacheLocks();
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_sid_lookup  = ServerSessionIDLookup;
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_sid_cache   = ServerSessionIDCache;
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_sid_uncache = ServerSessionIDUncache;
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!envString) {
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	envString  = getenv(envVarName);
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!envString) {
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SET_ERROR_CODE
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    myEnvString = PORT_Strdup(envString);
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!myEnvString)
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fmString = strchr(myEnvString, ',');
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!fmString)
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	goto loser;
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *fmString++ = 0;
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    decoString = ATOB_AsciiToData(myEnvString, &decoLen);
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!decoString) {
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	SET_ERROR_CODE
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (decoLen != sizeof inherit) {
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	SET_ERROR_CODE
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	goto loser;
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(&inherit, decoString, sizeof inherit);
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (strlen(fmString)  != inherit.fmStrLen ) {
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	goto loser;
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(cache, 0, sizeof *cache);
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMemSize	= inherit.cacheMemSize;
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Create cache */
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMemMap = PR_ImportFileMapFromString(fmString);
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(! cache->cacheMemMap) {
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMem = PR_MemMap(cache->cacheMemMap, 0, cache->cacheMemSize);
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (! cache->cacheMem) {
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sharedCache   = (cacheDesc *)cache->cacheMem;
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cache->sharedCache->cacheMemSize != cache->cacheMemSize) {
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SET_ERROR_CODE
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	goto loser;
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* We're now going to overwrite the local cache instance with the
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** shared copy of the cache struct, then update several values in
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** the local cache using the values for cache->cacheMemMap and
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** cache->cacheMem computed just above.  So, we copy cache into
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** the automatic variable "my", to preserve the variables while
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** cache is overwritten.
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    my = *cache;  /* save values computed above. */
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(cache, cache->sharedCache, sizeof *cache); /* overwrite */
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Fix pointers in our private copy of cache descriptor to point to
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** spaces in shared memory, whose address is now in "my".
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr = (ptrdiff_t)my.cacheMem;
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->sidCacheLocks) += ptr;
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->keyCacheLock ) += ptr;
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->certCacheLock) += ptr;
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr;
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->sidCacheSets ) += ptr;
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->sidCacheData ) += ptr;
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->certCacheData) += ptr;
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->keyCacheData ) += ptr;
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr;
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->ticketEncKey ) += ptr;
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->ticketMacKey ) += ptr;
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->ticketKeysValid) += ptr;
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(ptrdiff_t *)(&cache->srvNameCacheData) += ptr;
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMemMap = my.cacheMemMap;
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->cacheMem    = my.cacheMem;
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sharedCache = (cacheDesc *)cache->cacheMem;
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WINNT
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*  On Windows NT we need to "fix" the sidCacheLocks here to support fibers
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  When NT fibers are used in a multi-process server, a second level of
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  locking is needed to prevent a deadlock, in case a fiber acquires the
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  cross-process mutex, yields, and another fiber is later scheduled on
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  the same native thread and tries to acquire the cross-process mutex.
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  We do this by using a PRLock in the sslMutex. However, it is stored in
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  shared memory as part of sidCacheLocks, and we don't want to overwrite
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  the PRLock of the parent process. So we need to make new, private
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  copies of sidCacheLocks before modifying the sslMutex with our own
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  PRLock
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* note from jpierre : this should be free'd in child processes when
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** a function is added to delete the SSL session cache in the future.
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    locks_to_initialize = cache->numSIDCacheLocks + 3;
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newLocks = PORT_NewArray(sidCacheLock, locks_to_initialize);
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!newLocks)
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	goto loser;
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* copy the old locks */
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(newLocks, cache->sidCacheLocks,
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           locks_to_initialize * sizeof(sidCacheLock));
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sidCacheLocks = newLocks;
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* fix the locks */
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (; locks_initialized < locks_to_initialize; ++locks_initialized) {
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* now, make a local PRLock in this sslMutex for this child process */
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus err;
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        err = sslMutex_2LevelInit(&newLocks[locks_initialized].mutex);
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (err != SECSuccess) {
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cache->numSIDCacheLocksInitialized = locks_initialized;
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	}
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->numSIDCacheLocksInitialized = locks_initialized;
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* also fix the key and cert cache which use the last 2 lock entries */
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->keyCacheLock  = cache->sidCacheLocks + cache->numSIDCacheLocks;
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->certCacheLock = cache->keyCacheLock  + 1;
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->srvNameCacheLock = cache->certCacheLock  + 1;
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Free(myEnvString);
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Free(decoString);
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* mark that we have inherited this. */
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sharedCache->everInherited = PR_TRUE;
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    isMultiProcess = PR_TRUE;
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Free(myEnvString);
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (decoString)
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Free(decoString);
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseCache(cache);
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_InheritMPServerSIDCache(const char * envString)
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_InheritMPServerSIDCacheInstance(&globalCache, envString);
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(XP_UNIX) || defined(XP_BEOS)
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SID_LOCK_EXPIRATION_TIMEOUT  30 /* seconds */
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LockPoller(void * arg)
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *    cache         = (cacheDesc *)arg;
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *    sharedCache   = cache->sharedCache;
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidCacheLock * pLock;
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRIntervalTime timeout;
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32       now;
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32       then;
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int            locks_polled  = 0;
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int            locks_to_poll = cache->numSIDCacheLocks + 2;
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32       expiration    = cache->mutexTimeout;
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    timeout = PR_SecondsToInterval(expiration);
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while(!sharedCache->stopPolling) {
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PR_Sleep(timeout);
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sharedCache->stopPolling)
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	now   = ssl_Time();
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	then  = now - expiration;
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (pLock = cache->sidCacheLocks, locks_polled = 0;
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     locks_to_poll > locks_polled && !sharedCache->stopPolling;
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     ++locks_polled, ++pLock ) {
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    pid_t pid;
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (pLock->timeStamp   < then &&
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        pLock->timeStamp   != 0 &&
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(pid = pLock->pid) != 0) {
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	/* maybe we should try the lock? */
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int result = kill(pid, 0);
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (result < 0 && errno == ESRCH) {
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    SECStatus rv;
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* No process exists by that pid any more.
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ** Treat this mutex as abandoned.
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    */
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    pLock->timeStamp = now;
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    pLock->pid       = 0;
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    rv = sslMutex_Unlock(&pLock->mutex);
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (rv != SECSuccess) {
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    	/* Now what? */
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} /* end of loop over locks */
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } /* end of entire polling loop */
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Launch thread to poll cache for expired locks */
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LaunchLockPoller(cacheDesc *cache)
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char * timeoutString;
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRThread *   pollerThread;
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->mutexTimeout = SID_LOCK_EXPIRATION_TIMEOUT;
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    timeoutString       = getenv("NSS_SSL_SERVER_CACHE_MUTEX_TIMEOUT");
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (timeoutString) {
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	long newTime = strtol(timeoutString, 0, 0);
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (newTime == 0)
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECSuccess;  /* application doesn't want poller thread */
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (newTime > 0)
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cache->mutexTimeout = (PRUint32)newTime;
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* if error (newTime < 0) ignore it and use default */
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pollerThread =
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PR_CreateThread(PR_USER_THREAD, LockPoller, cache, PR_PRIORITY_NORMAL,
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pollerThread) {
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECFailure;
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->poller = pollerThread;
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Stop the thread that polls cache for expired locks */
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StopLockPoller(cacheDesc *cache)
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cache->poller) {
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECSuccess;
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->sharedCache->stopPolling = PR_TRUE;
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (PR_Interrupt(cache->poller) != PR_SUCCESS) {
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (PR_JoinThread(cache->poller) != PR_SUCCESS) {
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->poller = NULL;
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  Code dealing with shared wrapped symmetric wrapping keys below      *
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* If now is zero, it implies that the lock is not held, and must be
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** aquired here.
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)getSvrWrappingKey(PRInt32                symWrapMechIndex,
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SSL3KEAType               exchKeyType,
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SSLWrappedSymWrappingKey *wswk,
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       cacheDesc *               cache,
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       PRUint32                  lockTime)
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32  ndx = (exchKeyType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex;
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLWrappedSymWrappingKey * pwswk = cache->keyCacheData + ndx;
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32  now = 0;
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool    rv  = PR_FALSE;
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cache->cacheMem) { /* cache is uninitialized */
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED);
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!lockTime) {
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	lockTime = now = LockSidCacheLock(cache->keyCacheLock, now);
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!lockTime) {
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return rv;
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pwswk->exchKeyType      == exchKeyType &&
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pwswk->symWrapMechIndex == symWrapMechIndex &&
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pwswk->wrappedSymKeyLen != 0) {
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*wswk = *pwswk;
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PR_TRUE;
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (now) {
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	UnlockSidCacheLock(cache->keyCacheLock);
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_GetWrappingKey( PRInt32                   symWrapMechIndex,
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SSL3KEAType               exchKeyType,
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    SSLWrappedSymWrappingKey *wswk)
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool rv;
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert( (unsigned)exchKeyType < kt_kea_size);
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((unsigned)exchKeyType < kt_kea_size &&
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS) {
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = getSvrWrappingKey(symWrapMechIndex, exchKeyType, wswk,
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                       &globalCache, 0);
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	rv = PR_FALSE;
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Wrap and cache a session ticket key. */
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WrapTicketKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey,
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const char *keyName, encKeyCacheEntry* cacheEntry)
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem wrappedKey = {siBuffer, NULL, 0};
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey);
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(wrappedKey.len <= sizeof(cacheEntry->bytes));
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (wrappedKey.len > sizeof(cacheEntry->bytes))
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FALSE;
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrappedKey.data = cacheEntry->bytes;
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, symKey, &wrappedKey)
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    != SECSuccess) {
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%s]: Unable to wrap session ticket %s.",
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    SSL_GETPID(), "unknown", keyName));
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FALSE;
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheEntry->length = wrappedKey.len;
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_TRUE;
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey,
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   PK11SymKey **macKey)
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SlotInfo *slot;
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CK_MECHANISM_TYPE mechanismArray[2];
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey *aesKeyTmp = NULL;
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey *macKeyTmp = NULL;
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *cache = &globalCache;
1861a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN];
1862a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8 *ticketKeyNameSuffix;
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cache->cacheMem) {
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* cache is not initalized. Use stack buffer */
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ticketKeyNameSuffix = ticketKeyNameSuffixLocal;
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ticketKeyNameSuffix = cache->ticketKeyNameSuffix;
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (PK11_GenerateRandom(ticketKeyNameSuffix,
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess) {
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%s]: Unable to generate random key name bytes.",
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    SSL_GETPID(), "unknown"));
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mechanismArray[0] = CKM_AES_CBC;
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mechanismArray[1] = CKM_SHA256_HMAC;
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    slot = PK11_GetBestSlotMultiple(mechanismArray, 2, pwArg);
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (slot) {
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL,
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                AES_256_KEY_LENGTH, pwArg);
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL,
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SHA256_LENGTH, pwArg);
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSlot(slot);
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (aesKeyTmp == NULL || macKeyTmp == NULL) {
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%s]: Unable to generate session ticket keys.",
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    SSL_GETPID(), "unknown"));
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(keyName, ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN);
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *aesKey = aesKeyTmp;
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *macKey = macKeyTmp;
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_TRUE;
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (aesKeyTmp)
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSymKey(aesKeyTmp);
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (macKeyTmp)
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSymKey(macKeyTmp);
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FALSE;
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg,
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          unsigned char *keyName, PK11SymKey **aesKey,
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          PK11SymKey **macKey)
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey *aesKeyTmp = NULL;
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey *macKeyTmp = NULL;
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *cache = &globalCache;
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp)) {
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        goto loser;
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cache->cacheMem) {
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Export the keys to the shared cache in wrapped form. */
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey))
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            goto loser;
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey))
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            goto loser;
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *aesKey = aesKeyTmp;
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *macKey = macKeyTmp;
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_TRUE;
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (aesKeyTmp)
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSymKey(aesKeyTmp);
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (macKeyTmp)
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSymKey(macKeyTmp);
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FALSE;
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *keyName,
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       PK11SymKey **aesKey, PK11SymKey **macKey)
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem wrappedKey = {siBuffer, NULL, 0};
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey *aesKeyTmp = NULL;
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey *macKeyTmp = NULL;
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *cache = &globalCache;
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrappedKey.data = cache->ticketEncKey->bytes;
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrappedKey.len = cache->ticketEncKey->length;
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(wrappedKey.len <= sizeof(cache->ticketEncKey->bytes));
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aesKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CKM_AES_CBC, CKA_DECRYPT, 0);
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrappedKey.data = cache->ticketMacKey->bytes;
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrappedKey.len = cache->ticketMacKey->length;
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(wrappedKey.len <= sizeof(cache->ticketMacKey->bytes));
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    macKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CKM_SHA256_HMAC, CKA_SIGN, 0);
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (aesKeyTmp == NULL || macKeyTmp == NULL) {
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%s]: Unable to unwrap session ticket keys.",
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    SSL_GETPID(), "unknown"));
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_DBG(("%d: SSL[%s]: Successfully unwrapped session ticket keys.",
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_GETPID(), "unknown"));
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(keyName, cache->ticketKeyNameSuffix,
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SESS_TICKET_KEY_VAR_NAME_LEN);
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *aesKey = aesKeyTmp;
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *macKey = macKeyTmp;
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_TRUE;
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (aesKeyTmp)
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSymKey(aesKeyTmp);
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (macKeyTmp)
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSymKey(macKeyTmp);
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FALSE;
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               SECKEYPublicKey *svrPubKey, void *pwArg,
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               unsigned char *keyName, PK11SymKey **aesKey,
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PK11SymKey **macKey)
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 now = 0;
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool rv = PR_FALSE;
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool keysGenerated = PR_FALSE;
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *cache = &globalCache;
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cache->cacheMem) {
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* cache is uninitialized. Generate keys and return them
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * without caching. */
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return GenerateTicketKeys(pwArg, keyName, aesKey, macKey);
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = LockSidCacheLock(cache->keyCacheLock, now);
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!now)
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!*(cache->ticketKeysValid)) {
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Keys do not exist, create them. */
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!GenerateAndWrapTicketKeys(svrPubKey, pwArg, keyName,
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		aesKey, macKey))
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	keysGenerated = PR_TRUE;
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*(cache->ticketKeysValid) = 1;
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = PR_TRUE;
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loser:
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UnlockSidCacheLock(cache->keyCacheLock);
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv && !keysGenerated)
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = UnwrapCachedTicketKeys(svrPrivKey, keyName, aesKey, macKey);
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_GetSessionTicketKeys(unsigned char *keyName, unsigned char *encKey,
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         unsigned char *macKey)
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool rv = PR_FALSE;
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 now = 0;
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *cache = &globalCache;
2029a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8 ticketMacKey[SHA256_LENGTH], ticketEncKey[AES_256_KEY_LENGTH];
2030a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN];
2031a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8 *ticketMacKeyPtr, *ticketEncKeyPtr, *ticketKeyNameSuffix;
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool cacheIsEnabled = PR_TRUE;
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cache->cacheMem) { /* cache is uninitialized */
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cacheIsEnabled = PR_FALSE;
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ticketKeyNameSuffix = ticketKeyNameSuffixLocal;
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ticketEncKeyPtr = ticketEncKey;
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ticketMacKeyPtr = ticketMacKey;
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* these values have constant memory locations in the cache.
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * Ok to reference them without holding the lock. */
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ticketKeyNameSuffix = cache->ticketKeyNameSuffix;
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ticketEncKeyPtr = cache->ticketEncKey->bytes;
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ticketMacKeyPtr = cache->ticketMacKey->bytes;
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cacheIsEnabled) {
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Grab lock if initialized. */
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        now = LockSidCacheLock(cache->keyCacheLock, now);
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!now)
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return rv;
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Going to regenerate keys on every call if cache was not
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * initialized. */
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cacheIsEnabled || !*(cache->ticketKeysValid)) {
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (PK11_GenerateRandom(ticketKeyNameSuffix,
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess)
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (PK11_GenerateRandom(ticketEncKeyPtr,
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                AES_256_KEY_LENGTH) != SECSuccess)
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (PK11_GenerateRandom(ticketMacKeyPtr,
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SHA256_LENGTH) != SECSuccess)
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (cacheIsEnabled) {
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *(cache->ticketKeysValid) = 1;
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = PR_TRUE;
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loser:
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cacheIsEnabled) {
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UnlockSidCacheLock(cache->keyCacheLock);
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv) {
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(keyName, ticketKeyNameSuffix,
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SESS_TICKET_KEY_VAR_NAME_LEN);
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(encKey, ticketEncKeyPtr, AES_256_KEY_LENGTH);
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(macKey, ticketMacKeyPtr, SHA256_LENGTH);
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The caller passes in the new value it wants
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to set.  This code tests the wrapped sym key entry in the shared memory.
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If it is uninitialized, this function writes the caller's value into
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the disk entry, and returns false.
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Otherwise, it overwrites the caller's wswk with the value obtained from
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the disk, and returns PR_TRUE.
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is all done while holding the locks/mutexes necessary to make
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the operation atomic.
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cacheDesc *   cache            = &globalCache;
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool        rv               = PR_FALSE;
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL3KEAType   exchKeyType      = wswk->exchKeyType;
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                /* type of keys used to wrap SymWrapKey*/
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32       symWrapMechIndex = wswk->symWrapMechIndex;
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32      ndx;
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32      now = 0;
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLWrappedSymWrappingKey myWswk;
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cache->cacheMem) { /* cache is uninitialized */
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED);
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert( (unsigned)exchKeyType < kt_kea_size);
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((unsigned)exchKeyType >= kt_kea_size)
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return 0;
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((unsigned)symWrapMechIndex >=  SSL_NUM_WRAP_MECHS)
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return 0;
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ndx = (exchKeyType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex;
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memset(&myWswk, 0, sizeof myWswk);	/* eliminate UMRs. */
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = LockSidCacheLock(cache->keyCacheLock, now);
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (now) {
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = getSvrWrappingKey(wswk->symWrapMechIndex, wswk->exchKeyType,
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                       &myWswk, cache, now);
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv) {
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* we found it on disk, copy it out to the caller. */
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Memcpy(wswk, &myWswk, sizeof *wswk);
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Wasn't on disk, and we're still holding the lock, so write it. */
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cache->keyCacheData[ndx] = *wswk;
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	UnlockSidCacheLock(cache->keyCacheLock);
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else  /* MAC version or other platform */
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "seccomon.h"
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "cert.h"
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ssl.h"
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslimpl.h"
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ConfigServerSessionIDCache(	int      maxCacheEntries,
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				PRUint32 ssl2_timeout,
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       	PRUint32 ssl3_timeout,
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  const char *   directory)
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigServerSessionIDCache)");
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ConfigMPServerSIDCache(	int      maxCacheEntries,
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				PRUint32 ssl2_timeout,
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       	PRUint32 ssl3_timeout,
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		          const char *   directory)
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigMPServerSIDCache)");
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_InheritMPServerSIDCache(const char * envString)
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_InheritMPServerSIDCache)");
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_GetWrappingKey( PRInt32                   symWrapMechIndex,
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SSL3KEAType               exchKeyType,
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    SSLWrappedSymWrappingKey *wswk)
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool rv = PR_FALSE;
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_GetWrappingKey)");
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This is a kind of test-and-set.  The caller passes in the new value it wants
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to set.  This code tests the wrapped sym key entry in the shared memory.
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If it is uninitialized, this function writes the caller's value into
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the disk entry, and returns false.
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Otherwise, it overwrites the caller's wswk with the value obtained from
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the disk, and returns PR_TRUE.
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is all done while holding the locks/mutexes necessary to make
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the operation atomic.
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool        rv = PR_FALSE;
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_SetWrappingKey)");
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRUint32
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetMaxServerCacheLocks(void)
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_GetMaxServerCacheLocks)");
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetMaxServerCacheLocks(PRUint32 maxLocks)
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_SetMaxServerCacheLocks)");
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* XP_UNIX || XP_WIN32 */
2214