| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file implements the CLIENT Session ID cache. | 2 * This file implements the CLIENT Session ID cache. |
| 3 * | 3 * |
| 4 * This Source Code Form is subject to the terms of the Mozilla Public | 4 * This Source Code Form is subject to the terms of the Mozilla Public |
| 5 * License, v. 2.0. If a copy of the MPL was not distributed with this | 5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 7 | 7 |
| 8 #include "cert.h" | 8 #include "cert.h" |
| 9 #include "pk11pub.h" | 9 #include "pk11pub.h" |
| 10 #include "secitem.h" | 10 #include "secitem.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 * | 28 * |
| 29 * never_cached, created, but not yet put into cache. | 29 * never_cached, created, but not yet put into cache. |
| 30 * in_client_cache, in the client cache's linked list. | 30 * in_client_cache, in the client cache's linked list. |
| 31 * in_server_cache, entry came from the server's cache file. | 31 * in_server_cache, entry came from the server's cache file. |
| 32 * invalid_cache has been removed from the cache. | 32 * invalid_cache has been removed from the cache. |
| 33 */ | 33 */ |
| 34 | 34 |
| 35 #define LOCK_CACHE lock_cache() | 35 #define LOCK_CACHE lock_cache() |
| 36 #define UNLOCK_CACHE PZ_Unlock(cacheLock) | 36 #define UNLOCK_CACHE PZ_Unlock(cacheLock) |
| 37 | 37 |
| 38 static PRCallOnceType lockOnce; |
| 39 |
| 40 /* FreeSessionCacheLocks is a callback from NSS_RegisterShutdown which destroys |
| 41 * the session cache locks on shutdown and resets them to their initial |
| 42 * state. */ |
| 38 static SECStatus | 43 static SECStatus |
| 39 ssl_InitClientSessionCacheLock(void) | 44 FreeSessionCacheLocks(void* appData, void* nssData) |
| 40 { | 45 { |
| 41 cacheLock = PZ_NewLock(nssILockCache); | 46 static const PRCallOnceType pristineCallOnce; |
| 42 return cacheLock ? SECSuccess : SECFailure; | 47 SECStatus rv; |
| 43 } | |
| 44 | 48 |
| 45 static SECStatus | 49 if (!cacheLock) { |
| 46 ssl_FreeClientSessionCacheLock(void) | |
| 47 { | |
| 48 if (cacheLock) { | |
| 49 PZ_DestroyLock(cacheLock); | |
| 50 cacheLock = NULL; | |
| 51 return SECSuccess; | |
| 52 } | |
| 53 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); | |
| 54 return SECFailure; | |
| 55 } | |
| 56 | |
| 57 static PRBool LocksInitializedEarly = PR_FALSE; | |
| 58 | |
| 59 static SECStatus | |
| 60 FreeSessionCacheLocks() | |
| 61 { | |
| 62 SECStatus rv1, rv2; | |
| 63 rv1 = ssl_FreeSymWrapKeysLock(); | |
| 64 rv2 = ssl_FreeClientSessionCacheLock(); | |
| 65 if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) { | |
| 66 return SECSuccess; | |
| 67 } | |
| 68 return SECFailure; | |
| 69 } | |
| 70 | |
| 71 static SECStatus | |
| 72 InitSessionCacheLocks(void) | |
| 73 { | |
| 74 SECStatus rv1, rv2; | |
| 75 PRErrorCode rc; | |
| 76 rv1 = ssl_InitSymWrapKeysLock(); | |
| 77 rv2 = ssl_InitClientSessionCacheLock(); | |
| 78 if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) { | |
| 79 return SECSuccess; | |
| 80 } | |
| 81 rc = PORT_GetError(); | |
| 82 FreeSessionCacheLocks(); | |
| 83 PORT_SetError(rc); | |
| 84 return SECFailure; | |
| 85 } | |
| 86 | |
| 87 /* free the session cache locks if they were initialized early */ | |
| 88 SECStatus | |
| 89 ssl_FreeSessionCacheLocks() | |
| 90 { | |
| 91 PORT_Assert(PR_TRUE == LocksInitializedEarly); | |
| 92 if (!LocksInitializedEarly) { | |
| 93 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); | 50 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); |
| 94 return SECFailure; | 51 return SECFailure; |
| 95 } | 52 } |
| 96 FreeSessionCacheLocks(); | 53 |
| 97 LocksInitializedEarly = PR_FALSE; | 54 PZ_DestroyLock(cacheLock); |
| 55 cacheLock = NULL; |
| 56 |
| 57 rv = ssl_FreeSymWrapKeysLock(); |
| 58 if (rv != SECSuccess) { |
| 59 return rv; |
| 60 } |
| 61 |
| 62 lockOnce = pristineCallOnce; |
| 98 return SECSuccess; | 63 return SECSuccess; |
| 99 } | 64 } |
| 100 | 65 |
| 101 static PRCallOnceType lockOnce; | 66 /* InitSessionCacheLocks is called, protected by lockOnce, to create the |
| 67 * session cache locks. */ |
| 68 static PRStatus |
| 69 InitSessionCacheLocks(void) |
| 70 { |
| 71 SECStatus rv; |
| 102 | 72 |
| 103 /* free the session cache locks if they were initialized lazily */ | 73 cacheLock = PZ_NewLock(nssILockCache); |
| 104 static SECStatus ssl_ShutdownLocks(void* appData, void* nssData) | 74 if (cacheLock == NULL) { |
| 105 { | |
| 106 PORT_Assert(PR_FALSE == LocksInitializedEarly); | |
| 107 if (LocksInitializedEarly) { | |
| 108 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
| 109 return SECFailure; | |
| 110 } | |
| 111 FreeSessionCacheLocks(); | |
| 112 memset(&lockOnce, 0, sizeof(lockOnce)); | |
| 113 return SECSuccess; | |
| 114 } | |
| 115 | |
| 116 static PRStatus initSessionCacheLocksLazily(void) | |
| 117 { | |
| 118 SECStatus rv = InitSessionCacheLocks(); | |
| 119 if (SECSuccess != rv) { | |
| 120 return PR_FAILURE; | 75 return PR_FAILURE; |
| 121 } | 76 } |
| 122 rv = NSS_RegisterShutdown(ssl_ShutdownLocks, NULL); | 77 rv = ssl_InitSymWrapKeysLock(); |
| 78 if (rv != SECSuccess) { |
| 79 PRErrorCode error = PORT_GetError(); |
| 80 PZ_DestroyLock(cacheLock); |
| 81 cacheLock = NULL; |
| 82 PORT_SetError(error); |
| 83 return PR_FAILURE; |
| 84 } |
| 85 |
| 86 rv = NSS_RegisterShutdown(FreeSessionCacheLocks, NULL); |
| 123 PORT_Assert(SECSuccess == rv); | 87 PORT_Assert(SECSuccess == rv); |
| 124 if (SECSuccess != rv) { | 88 if (SECSuccess != rv) { |
| 125 return PR_FAILURE; | 89 return PR_FAILURE; |
| 126 } | 90 } |
| 127 return PR_SUCCESS; | 91 return PR_SUCCESS; |
| 128 } | 92 } |
| 129 | 93 |
| 130 /* lazyInit means that the call is not happening during a 1-time | |
| 131 * initialization function, but rather during dynamic, lazy initialization | |
| 132 */ | |
| 133 SECStatus | 94 SECStatus |
| 134 ssl_InitSessionCacheLocks(PRBool lazyInit) | 95 ssl_InitSessionCacheLocks(void) |
| 135 { | 96 { |
| 136 if (LocksInitializedEarly) { | 97 return (PR_SUCCESS == |
| 137 return SECSuccess; | 98 PR_CallOnce(&lockOnce, InitSessionCacheLocks)) ? |
| 138 } | 99 SECSuccess : SECFailure; |
| 139 | |
| 140 if (lazyInit) { | |
| 141 return (PR_SUCCESS == | |
| 142 PR_CallOnce(&lockOnce, initSessionCacheLocksLazily)) ? | |
| 143 SECSuccess : SECFailure; | |
| 144 } | |
| 145 | |
| 146 if (SECSuccess == InitSessionCacheLocks()) { | |
| 147 LocksInitializedEarly = PR_TRUE; | |
| 148 return SECSuccess; | |
| 149 } | |
| 150 | |
| 151 return SECFailure; | |
| 152 } | 100 } |
| 153 | 101 |
| 154 static void | 102 static void |
| 155 lock_cache(void) | 103 lock_cache(void) |
| 156 { | 104 { |
| 157 ssl_InitSessionCacheLocks(PR_TRUE); | 105 ssl_InitSessionCacheLocks(); |
| 158 PZ_Lock(cacheLock); | 106 PZ_Lock(cacheLock); |
| 159 } | 107 } |
| 160 | 108 |
| 161 /* BEWARE: This function gets called for both client and server SIDs !! | 109 /* BEWARE: This function gets called for both client and server SIDs !! |
| 162 * If the unreferenced sid is not in the cache, Free sid and its contents. | 110 * If the unreferenced sid is not in the cache, Free sid and its contents. |
| 163 */ | 111 */ |
| 164 static void | 112 static void |
| 165 ssl_DestroySID(sslSessionID *sid) | 113 ssl_DestroySID(sslSessionID *sid) |
| 166 { | 114 { |
| 167 int i; | 115 int i; |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 sid->u.ssl3.sessionTicket.ticket.len = 0; | 447 sid->u.ssl3.sessionTicket.ticket.len = 0; |
| 500 } | 448 } |
| 501 sid->u.ssl3.sessionTicket.received_timestamp = | 449 sid->u.ssl3.sessionTicket.received_timestamp = |
| 502 session_ticket->received_timestamp; | 450 session_ticket->received_timestamp; |
| 503 sid->u.ssl3.sessionTicket.ticket_lifetime_hint = | 451 sid->u.ssl3.sessionTicket.ticket_lifetime_hint = |
| 504 session_ticket->ticket_lifetime_hint; | 452 session_ticket->ticket_lifetime_hint; |
| 505 | 453 |
| 506 UNLOCK_CACHE; | 454 UNLOCK_CACHE; |
| 507 return SECSuccess; | 455 return SECSuccess; |
| 508 } | 456 } |
| OLD | NEW |