15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This file implements the CLIENT Session ID cache.
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)#include "cert.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pk11pub.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "secitem.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ssl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nss.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslimpl.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslproto.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nssilock.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRUint32 ssl_sid_timeout = 100;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static sslSessionID *cache = NULL;
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static PZLock *      cacheLock = NULL;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* sids can be in one of 4 states:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * never_cached, 	created, but not yet put into cache.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in_client_cache, 	in the client cache's linked list.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in_server_cache, 	entry came from the server's cache file.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * invalid_cache	has been removed from the cache.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOCK_CACHE 	lock_cache()
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UNLOCK_CACHE	PZ_Unlock(cacheLock)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)static PRCallOnceType lockOnce;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)/* FreeSessionCacheLocks is a callback from NSS_RegisterShutdown which destroys
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) * the session cache locks on shutdown and resets them to their initial
4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) * state. */
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)FreeSessionCacheLocks(void* appData, void* nssData)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    static const PRCallOnceType pristineCallOnce;
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SECStatus rv;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!cacheLock) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECFailure;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    PZ_DestroyLock(cacheLock);
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    cacheLock = NULL;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    rv = ssl_FreeSymWrapKeysLock();
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (rv != SECSuccess) {
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        return rv;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    lockOnce = pristineCallOnce;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)/* InitSessionCacheLocks is called, protected by lockOnce, to create the
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) * session cache locks. */
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)static PRStatus
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)InitSessionCacheLocks(void)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SECStatus rv;
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    cacheLock = PZ_NewLock(nssILockCache);
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (cacheLock == NULL) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return PR_FAILURE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    rv = ssl_InitSymWrapKeysLock();
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (rv != SECSuccess) {
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        PRErrorCode error = PORT_GetError();
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        PZ_DestroyLock(cacheLock);
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        cacheLock = NULL;
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        PORT_SetError(error);
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        return PR_FAILURE;
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    rv = NSS_RegisterShutdown(FreeSessionCacheLocks, NULL);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(SECSuccess == rv);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SECSuccess != rv) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return PR_FAILURE;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_SUCCESS;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ssl_InitSessionCacheLocks(void)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return (PR_SUCCESS ==
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            PR_CallOnce(&lockOnce, InitSessionCacheLocks)) ?
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)           SECSuccess : SECFailure;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)static void
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lock_cache(void)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ssl_InitSessionCacheLocks();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PZ_Lock(cacheLock);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* BEWARE: This function gets called for both client and server SIDs !!
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the unreferenced sid is not in the cache, Free sid and its contents.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_DestroySID(sslSessionID *sid)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached));
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PORT_Assert(sid->references == 0);
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PORT_Assert(sid->cached != in_client_cache);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE);
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             PR_FALSE);
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (sid->u.ssl3.srvName.data) {
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (sid->u.ssl3.originalHandshakeHash.data) {
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE);
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (sid->u.ssl3.signedCertTimestamps.data) {
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE);
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (sid->u.ssl3.lock) {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            NSSRWLock_Destroy(sid->u.ssl3.lock);
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sid->peerID != NULL)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Free((void *)sid->peerID);		/* CONST */
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sid->urlSvrName != NULL)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Free((void *)sid->urlSvrName);	/* CONST */
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ( sid->peerCert ) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CERT_DestroyCertificate(sid->peerCert);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CERT_DestroyCertificate(sid->peerCertChain[i]);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (sid->peerCertStatus.items) {
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        SECITEM_FreeArray(&sid->peerCertStatus, PR_FALSE);
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ( sid->localCert ) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CERT_DestroyCertificate(sid->localCert);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_ZFree(sid, sizeof(sslSessionID));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* BEWARE: This function gets called for both client and server SIDs !!
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Decrement reference count, and
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    free sid if ref count is zero, and sid is not in the cache.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Does NOT remove from the cache first.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the sid is still in the cache, it is left there until next time
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the cache list is traversed.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FreeLockedSID(sslSessionID *sid)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(sid->references >= 1);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (--sid->references == 0) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_DestroySID(sid);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* BEWARE: This function gets called for both client and server SIDs !!
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Decrement reference count, and
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    free sid if ref count is zero, and sid is not in the cache.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Does NOT remove from the cache first.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These locks are necessary because the sid _might_ be in the cache list.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FreeSID(sslSessionID *sid)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOCK_CACHE;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_FreeLockedSID(sid);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNLOCK_CACHE;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************/
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Lookup sid entry in cache by Address, port, and peerID string.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  If found, Increment reference count, and return pointer to caller.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  If it has timed out or ref count is zero, remove from list and free it.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslSessionID *
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const char * urlSvrName)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSessionID **sidp;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSessionID * sid;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32       now;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!urlSvrName)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return NULL;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = ssl_Time();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOCK_CACHE;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sidp = &cache;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((sid = *sidp) != 0) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(sid->cached == in_client_cache);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(sid->references >= 1);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_TRC(8, ("SSL: Lookup1: sid=0x%x", sid));
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	if (sid->expirationTime < now) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	    ** This session-id timed out.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ** Don't even care who it belongs to, blow it out of our cache.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    */
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRC(7, ("SSL: lookup1, throwing sid out, age=%d refs=%d",
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			now - sid->creationTime, sid->references));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *sidp = sid->next; 			/* delink it from the list. */
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->cached = invalid_cache;	/* mark not on list. */
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	    ssl_FreeLockedSID(sid);		/* drop ref count, free. */
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (!memcmp(&sid->addr, addr, sizeof(PRIPv6Addr)) && /* server IP addr matches */
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	           (sid->port == port) && /* server port matches */
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   /* proxy (peerID) matches */
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (((peerID == NULL) && (sid->peerID == NULL)) ||
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ((peerID != NULL) && (sid->peerID != NULL) &&
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     PORT_Strcmp(sid->peerID, peerID) == 0)) &&
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   /* is cacheable */
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (sid->version < SSL_LIBRARY_VERSION_3_0 ||
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sid->u.ssl3.keys.resumable) &&
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   /* server hostname matches. */
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	           (sid->urlSvrName != NULL) &&
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   ((0 == PORT_Strcmp(urlSvrName, sid->urlSvrName)) ||
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ((sid->peerCert != NULL) && (SECSuccess ==
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      CERT_VerifyCertName(sid->peerCert, urlSvrName))) )
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  ) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Hit */
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->lastAccessTime = now;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->references++;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sidp = &sid->next;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNLOCK_CACHE;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sid;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Add an sid to the cache or return a previously cached entry to the cache.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Although this is static, it is called via ss->sec.cache().
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CacheSID(sslSessionID *sid)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32  expirationPeriod;
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PORT_Assert(sid->cached == never_cached);
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_TRC(8, ("SSL: Cache: sid=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"time=%x cached=%d",
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sid, sid->cached, sid->addr.pr_s6_addr32[0],
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2],
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sid->addr.pr_s6_addr32[3],  sid->port, sid->creationTime,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sid->cached));
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!sid->urlSvrName) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* don't cache this SID because it can never be matched */
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* XXX should be different trace for version 2 vs. version 3 */
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	expirationPeriod = ssl_sid_timeout;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "sessionID:",
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID)));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "masterKey:",
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  sid->u.ssl2.masterKey.data, sid->u.ssl2.masterKey.len));
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "cipherArg:",
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  sid->u.ssl2.cipherArg.data, sid->u.ssl2.cipherArg.len));
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sid->u.ssl3.sessionIDLength == 0 &&
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	    sid->u.ssl3.locked.sessionTicket.ticket.data == NULL)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Client generates the SessionID if this was a stateless resume. */
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sid->u.ssl3.sessionIDLength == 0) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SECStatus rv;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = PK11_GenerateRandom(sid->u.ssl3.sessionID,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL3_SESSIONID_BYTES);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	expirationPeriod = ssl3_sid_timeout;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "sessionID:",
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength));
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	sid->u.ssl3.lock = NSSRWLock_New(NSS_RWLOCK_RANK_NONE, NULL);
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	if (!sid->u.ssl3.lock) {
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	    return;
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!sid->creationTime)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sid->lastAccessTime = sid->creationTime = ssl_Time();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!sid->expirationTime)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sid->expirationTime = sid->creationTime + expirationPeriod;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Put sid into the cache.  Bump reference count to indicate that
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * cache is holding a reference. Uncache will reduce the cache
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * reference.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOCK_CACHE;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sid->references++;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sid->cached = in_client_cache;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sid->next   = cache;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache       = sid;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNLOCK_CACHE;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If sid "zap" is in the cache,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    removes sid from cache, and decrements reference count.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Caller must hold cache lock.
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UncacheSID(sslSessionID *zap)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSessionID **sidp = &cache;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSessionID *sid;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (zap->cached != in_client_cache) {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_TRC(8,("SSL: Uncache: zap=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       "time=%x cipher=%d",
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       zap, zap->cached, zap->addr.pr_s6_addr32[0],
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       zap->addr.pr_s6_addr32[1], zap->addr.pr_s6_addr32[2],
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       zap->addr.pr_s6_addr32[3], zap->port, zap->creationTime,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       zap->u.ssl2.cipherType));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (zap->version < SSL_LIBRARY_VERSION_3_0) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "sessionID:",
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      zap->u.ssl2.sessionID, sizeof(zap->u.ssl2.sessionID)));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "masterKey:",
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      zap->u.ssl2.masterKey.data, zap->u.ssl2.masterKey.len));
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRINT_BUF(8, (0, "cipherArg:",
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      zap->u.ssl2.cipherArg.data, zap->u.ssl2.cipherArg.len));
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* See if it's in the cache, if so nuke it */
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((sid = *sidp) != 0) {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sid == zap) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ** Bingo. Reduce reference count by one so that when
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ** everyone is done with the sid we can free it up.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    */
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *sidp = zap->next;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    zap->cached = invalid_cache;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_FreeLockedSID(zap);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sidp = &sid->next;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* If sid "zap" is in the cache,
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    removes sid from cache, and decrements reference count.
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Although this function is static, it is called externally via
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    ss->sec.uncache().
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LockAndUncacheSID(sslSessionID *zap)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOCK_CACHE;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UncacheSID(zap);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNLOCK_CACHE;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* choose client or server cache functions for this sslsocket. */
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_ChooseSessionIDProcs(sslSecurityInfo *sec)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sec->isServer) {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sec->cache   = ssl_sid_cache;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sec->uncache = ssl_sid_uncache;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sec->cache   = CacheSID;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sec->uncache = LockAndUncacheSID;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* wipe out the entire client session cache. */
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ClearSessionCache(void)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOCK_CACHE;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while(cache != NULL)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	UncacheSID(cache);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNLOCK_CACHE;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* returns an unsigned int containing the number of seconds in PR_Now() */
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRUint32
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Time(void)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 myTime;
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    myTime = time(NULL);	/* accurate until the year 2038. */
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* portable, but possibly slower */
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRTime now;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt64 ll;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = PR_Now();
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LL_I2L(ll, 1000000L);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LL_DIV(now, now, ll);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LL_L2UI(myTime, now);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return myTime;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ssl3_SetSIDSessionTicket(sslSessionID *sid,
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         /*in/out*/ NewSessionTicket *newSessionTicket)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PORT_Assert(sid);
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PORT_Assert(newSessionTicket);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    /* if sid->u.ssl3.lock, we are updating an existing entry that is already
4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * cached or was once cached, so we need to acquire and release the write
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * lock. Otherwise, this is a new session that isn't shared with anything
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * yet, so no locking is needed.
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (sid->u.ssl3.lock) {
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	NSSRWLock_LockWrite(sid->u.ssl3.lock);
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	/* A server might have sent us an empty ticket, which has the
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * effect of clearing the previously known ticket.
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 */
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	    SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)			     PR_FALSE);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PORT_Assert(!sid->u.ssl3.locked.sessionTicket.ticket.data);
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    /* Do a shallow copy, moving the ticket data. */
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sid->u.ssl3.locked.sessionTicket = *newSessionTicket;
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    newSessionTicket->ticket.data = NULL;
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    newSessionTicket->ticket.len = 0;
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (sid->u.ssl3.lock) {
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	NSSRWLock_UnlockWrite(sid->u.ssl3.lock);
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
473