| OLD | NEW |
| 1 /* This file implements the SERVER Session ID cache. | 1 /* This file implements the SERVER Session ID cache. |
| 2 * NOTE: The contents of this file are NOT used by the client. | 2 * NOTE: The contents of this file are NOT used by the client. |
| 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 /* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server | 8 /* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server |
| 9 * cache sids! | 9 * cache sids! |
| 10 * | 10 * |
| 11 * About record locking among different server processes: | 11 * About record locking among different server processes: |
| 12 * | 12 * |
| 13 * All processes that are part of the same conceptual server (serving on | 13 * All processes that are part of the same conceptual server (serving on |
| 14 * the same address and port) MUST share a common SSL session cache. | 14 * the same address and port) MUST share a common SSL session cache. |
| 15 * This code makes the content of the shared cache accessible to all | 15 * This code makes the content of the shared cache accessible to all |
| 16 * processes on the same "server". This code works on Unix and Win32 only. | 16 * processes on the same "server". This code works on Unix and Win32 only. |
| 17 * | 17 * |
| 18 * We use NSPR anonymous shared memory and move data to & from shared memory. | 18 * We use NSPR anonymous shared memory and move data to & from shared memory. |
| 19 * We must do explicit locking of the records for all reads and writes. | 19 * We must do explicit locking of the records for all reads and writes. |
| 20 * The set of Cache entries are divided up into "sets" of 128 entries. | 20 * The set of Cache entries are divided up into "sets" of 128 entries. |
| 21 * Each set is protected by a lock. There may be one or more sets protected | 21 * Each set is protected by a lock. There may be one or more sets protected |
| 22 * by each lock. That is, locks to sets are 1:N. | 22 * by each lock. That is, locks to sets are 1:N. |
| 23 * There is one lock for the entire cert cache. | 23 * There is one lock for the entire cert cache. |
| 24 * There is one lock for the set of wrapped sym wrap keys. | 24 * There is one lock for the set of wrapped sym wrap keys. |
| 25 * | 25 * |
| 26 * The anonymous shared memory is laid out as if it were declared like this: | 26 * The anonymous shared memory is laid out as if it were declared like this: |
| 27 * | 27 * |
| 28 * struct { | 28 * struct { |
| 29 * cacheDescriptor desc; | 29 * cacheDescriptor desc; |
| 30 * sidCacheLock sidCacheLocks[ numSIDCacheLocks]; | 30 * sidCacheLock sidCacheLocks[ numSIDCacheLocks]; |
| 31 * sidCacheLock keyCacheLock; | 31 * sidCacheLock keyCacheLock; |
| 32 * sidCacheLock certCacheLock; | 32 * sidCacheLock certCacheLock; |
| 33 * sidCacheSet sidCacheSets[ numSIDCacheSets ]; | 33 * sidCacheSet sidCacheSets[ numSIDCacheSets ]; |
| 34 * sidCacheEntry sidCacheData[ numSIDCacheEntries]; | 34 * sidCacheEntry sidCacheData[ numSIDCacheEntries]; |
| 35 * certCacheEntry certCacheData[numCertCacheEntries]; | 35 * certCacheEntry certCacheData[numCertCacheEntries]; |
| 36 * SSLWrappedSymWrappingKey keyCacheData[kt_kea_size][SSL_NUM_WRAP_MECHS]; | 36 * SSLWrappedSymWrappingKey keyCacheData[kt_kea_size][SSL_NUM_WRAP_MECHS]; |
| 37 * PRUint8 keyNameSuffix[SESS_TICKET_KEY_VAR_NAME_LEN] | 37 * PRUint8 keyNameSuffix[SESS_TICKET_KEY_VAR_NAME_LEN] |
| 38 * encKeyCacheEntry ticketEncKey; // Wrapped in non-bypass mode | 38 * encKeyCacheEntry ticketEncKey; // Wrapped in non-bypass mode |
| 39 * encKeyCacheEntry ticketMacKey; // Wrapped in non-bypass mode | 39 * encKeyCacheEntry ticketMacKey; // Wrapped in non-bypass mode |
| 40 * PRBool ticketKeysValid; | 40 * PRBool ticketKeysValid; |
| 41 * sidCacheLock srvNameCacheLock; | 41 * sidCacheLock srvNameCacheLock; |
| 42 * srvNameCacheEntry srvNameData[ numSrvNameCacheEntries ]; | 42 * srvNameCacheEntry srvNameData[ numSrvNameCacheEntries ]; |
| 43 * } cacheMemCacheData; | 43 * } cacheMemCacheData; |
| 44 */ | 44 */ |
| 45 #include "seccomon.h" | 45 #include "seccomon.h" |
| 46 | 46 |
| 47 #if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS
) | 47 #if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_OS2) || defined(XP_BEOS) |
| 48 | 48 |
| 49 #include "cert.h" | 49 #include "cert.h" |
| 50 #include "ssl.h" | 50 #include "ssl.h" |
| 51 #include "sslimpl.h" | 51 #include "sslimpl.h" |
| 52 #include "sslproto.h" | 52 #include "sslproto.h" |
| 53 #include "pk11func.h" | 53 #include "pk11func.h" |
| 54 #include "base64.h" | 54 #include "base64.h" |
| 55 #include "keyhi.h" | 55 #include "keyhi.h" |
| 56 #ifdef NO_PKCS11_BYPASS | 56 #ifdef NO_PKCS11_BYPASS |
| 57 #include "blapit.h" | 57 #include "blapit.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 71 #include <signal.h> | 71 #include <signal.h> |
| 72 #include "unix_err.h" | 72 #include "unix_err.h" |
| 73 | 73 |
| 74 #else | 74 #else |
| 75 | 75 |
| 76 #ifdef XP_WIN32 | 76 #ifdef XP_WIN32 |
| 77 #include <wtypes.h> | 77 #include <wtypes.h> |
| 78 #include "win32err.h" | 78 #include "win32err.h" |
| 79 #endif | 79 #endif |
| 80 | 80 |
| 81 #endif | 81 #endif |
| 82 #include <sys/types.h> | 82 #include <sys/types.h> |
| 83 | 83 |
| 84 #define SET_ERROR_CODE /* reminder */ | 84 #define SET_ERROR_CODE /* reminder */ |
| 85 | 85 |
| 86 #include "nspr.h" | 86 #include "nspr.h" |
| 87 #include "sslmutex.h" | 87 #include "sslmutex.h" |
| 88 | 88 |
| 89 /* | 89 /* |
| 90 ** Format of a cache entry in the shared memory. | 90 ** Format of a cache entry in the shared memory. |
| 91 */ | 91 */ |
| 92 struct sidCacheEntryStr { | 92 struct sidCacheEntryStr { |
| 93 /* 16 */ PRIPv6Addr addr;» /* client's IP address */ | 93 /* 16 */ PRIPv6Addr addr; /* client's IP address */ |
| 94 /* 4 */ PRUint32 creationTime; | 94 /* 4 */ PRUint32 creationTime; |
| 95 /* 4 */ PRUint32 lastAccessTime;» | 95 /* 4 */ PRUint32 lastAccessTime; |
| 96 /* 4 */ PRUint32 expirationTime; | 96 /* 4 */ PRUint32 expirationTime; |
| 97 /* 2 */ PRUint16» version; | 97 /* 2 */ PRUint16 version; |
| 98 /* 1 */ PRUint8» valid; | 98 /* 1 */ PRUint8 valid; |
| 99 /* 1 */ PRUint8 sessionIDLength; | 99 /* 1 */ PRUint8 sessionIDLength; |
| 100 /* 32 */ PRUint8 sessionID[SSL3_SESSIONID_BYTES]; | 100 /* 32 */ PRUint8 sessionID[SSL3_SESSIONID_BYTES]; |
| 101 /* 2 */ PRUint16 authAlgorithm; | 101 /* 2 */ PRUint16 authAlgorithm; |
| 102 /* 2 */ PRUint16 authKeyBits; | 102 /* 2 */ PRUint16 authKeyBits; |
| 103 /* 2 */ PRUint16 keaType; | 103 /* 2 */ PRUint16 keaType; |
| 104 /* 2 */ PRUint16 keaKeyBits; | 104 /* 2 */ PRUint16 keaKeyBits; |
| 105 /* 72 - common header total */ | 105 /* 72 - common header total */ |
| 106 | 106 |
| 107 union { | 107 union { |
| 108 » struct { | 108 struct { |
| 109 /* 64 */ PRUint8» masterKey[SSL_MAX_MASTER_KEY_BYTES]; | 109 /* 64 */ PRUint8 masterKey[SSL_MAX_MASTER_KEY_BYTES]; |
| 110 /* 32 */ PRUint8» cipherArg[SSL_MAX_CYPHER_ARG_BYTES]; | 110 /* 32 */ PRUint8 cipherArg[SSL_MAX_CYPHER_ARG_BYTES]; |
| 111 | 111 |
| 112 /* 1 */ PRUint8» cipherType; | 112 /* 1 */ PRUint8 cipherType; |
| 113 /* 1 */ PRUint8» masterKeyLen; | 113 /* 1 */ PRUint8 masterKeyLen; |
| 114 /* 1 */ PRUint8» keyBits; | 114 /* 1 */ PRUint8 keyBits; |
| 115 /* 1 */ PRUint8» secretKeyBits; | 115 /* 1 */ PRUint8 secretKeyBits; |
| 116 /* 1 */ PRUint8» cipherArgLen; | 116 /* 1 */ PRUint8 cipherArgLen; |
| 117 /*101 */} ssl2; | 117 /*101 */} ssl2; |
| 118 | 118 |
| 119 » struct { | 119 struct { |
| 120 /* 2 */ ssl3CipherSuite cipherSuite; | 120 /* 2 */ ssl3CipherSuite cipherSuite; |
| 121 /* 2 */ PRUint16 compression; » /* SSLCompressionMethod */ | 121 /* 2 */ PRUint16 compression; /* SSLCompressionMethod */ |
| 122 | 122 |
| 123 /* 54 */ ssl3SidKeys keys;» /* keys, wrapped as needed. */ | 123 /* 54 */ ssl3SidKeys keys; /* keys, wrapped as needed. */ |
| 124 | 124 |
| 125 /* 4 */ PRUint32 masterWrapMech; | 125 /* 4 */ PRUint32 masterWrapMech; |
| 126 /* 4 */ SSL3KEAType exchKeyType; | 126 /* 4 */ SSL3KEAType exchKeyType; |
| 127 /* 4 */ PRInt32 certIndex; | 127 /* 4 */ PRInt32 certIndex; |
| 128 /* 4 */ PRInt32 srvNameIndex; | 128 /* 4 */ PRInt32 srvNameIndex; |
| 129 /* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */ | 129 /* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */ |
| 130 /*108 */} ssl3; | 130 /*108 */} ssl3; |
| 131 |
| 131 /* force sizeof(sidCacheEntry) to be a multiple of cache line size */ | 132 /* force sizeof(sidCacheEntry) to be a multiple of cache line size */ |
| 132 struct { | 133 struct { |
| 133 /*120 */ PRUint8 filler[120]; /* 72+120==192, a multiple of 16 */ | 134 /*120 */ PRUint8 filler[120]; /* 72+120==192, a multiple of 16 */ |
| 134 » } forceSize; | 135 } forceSize; |
| 135 } u; | 136 } u; |
| 136 }; | 137 }; |
| 137 typedef struct sidCacheEntryStr sidCacheEntry; | 138 typedef struct sidCacheEntryStr sidCacheEntry; |
| 138 | 139 |
| 139 /* The length of this struct is supposed to be a power of 2, e.g. 4KB */ | 140 /* The length of this struct is supposed to be a power of 2, e.g. 4KB */ |
| 140 struct certCacheEntryStr { | 141 struct certCacheEntryStr { |
| 141 PRUint16 certLength;» » » » /* 2 */ | 142 PRUint16 certLength; /* 2 */ |
| 142 PRUint16 sessionIDLength;» » » /* 2 */ | 143 PRUint16 sessionIDLength; /* 2 */ |
| 143 PRUint8 » sessionID[SSL3_SESSIONID_BYTES];» /* 32 */ | 144 PRUint8 sessionID[SSL3_SESSIONID_BYTES]; /* 32 */ |
| 144 PRUint8 » cert[SSL_MAX_CACHED_CERT_LEN];» » /* 4060 */ | 145 PRUint8 cert[SSL_MAX_CACHED_CERT_LEN]; /* 4060 */ |
| 145 };» » » » » » /* total 4096 */ | 146 }; /* total 4096 */ |
| 146 typedef struct certCacheEntryStr certCacheEntry; | 147 typedef struct certCacheEntryStr certCacheEntry; |
| 147 | 148 |
| 148 struct sidCacheLockStr { | 149 struct sidCacheLockStr { |
| 149 PRUint32» timeStamp; | 150 PRUint32 timeStamp; |
| 150 sslMutex» mutex; | 151 sslMutex mutex; |
| 151 sslPID» pid; | 152 sslPID pid; |
| 152 }; | 153 }; |
| 153 typedef struct sidCacheLockStr sidCacheLock; | 154 typedef struct sidCacheLockStr sidCacheLock; |
| 154 | 155 |
| 155 struct sidCacheSetStr { | 156 struct sidCacheSetStr { |
| 156 PRIntn» next; | 157 PRIntn next; |
| 157 }; | 158 }; |
| 158 typedef struct sidCacheSetStr sidCacheSet; | 159 typedef struct sidCacheSetStr sidCacheSet; |
| 159 | 160 |
| 160 struct encKeyCacheEntryStr { | 161 struct encKeyCacheEntryStr { |
| 161 PRUint8» bytes[512]; | 162 PRUint8 bytes[512]; |
| 162 PRInt32» length; | 163 PRInt32 length; |
| 163 }; | 164 }; |
| 164 typedef struct encKeyCacheEntryStr encKeyCacheEntry; | 165 typedef struct encKeyCacheEntryStr encKeyCacheEntry; |
| 165 | 166 |
| 166 #define SSL_MAX_DNS_HOST_NAME 1024 | 167 #define SSL_MAX_DNS_HOST_NAME 1024 |
| 167 | 168 |
| 168 struct srvNameCacheEntryStr { | 169 struct srvNameCacheEntryStr { |
| 169 PRUint16 type; /* 2 */ | 170 PRUint16 type; /* 2 */ |
| 170 PRUint16 nameLen; /* 2 */ | 171 PRUint16 nameLen; /* 2 */ |
| 171 PRUint8» name[SSL_MAX_DNS_HOST_NAME + 12]; /* 1034 */ | 172 PRUint8 name[SSL_MAX_DNS_HOST_NAME + 12]; /* 1034 */ |
| 172 PRUint8 » nameHash[SHA256_LENGTH]; /* 32 */ | 173 PRUint8 nameHash[SHA256_LENGTH]; /* 32 */ |
| 173 /* 1072 */ | 174 /* 1072 */ |
| 174 }; | 175 }; |
| 175 typedef struct srvNameCacheEntryStr srvNameCacheEntry; | 176 typedef struct srvNameCacheEntryStr srvNameCacheEntry; |
| 176 | 177 |
| 177 | |
| 178 struct cacheDescStr { | 178 struct cacheDescStr { |
| 179 | 179 |
| 180 PRUint32 cacheMemSize; | 180 PRUint32 cacheMemSize; |
| 181 | 181 |
| 182 PRUint32» » numSIDCacheLocks; | 182 PRUint32 numSIDCacheLocks; |
| 183 PRUint32» » numSIDCacheSets; | 183 PRUint32 numSIDCacheSets; |
| 184 PRUint32» » numSIDCacheSetsPerLock; | 184 PRUint32 numSIDCacheSetsPerLock; |
| 185 | 185 |
| 186 PRUint32 numSIDCacheEntries; | 186 PRUint32 numSIDCacheEntries; |
| 187 PRUint32 sidCacheSize; | 187 PRUint32 sidCacheSize; |
| 188 | 188 |
| 189 PRUint32 numCertCacheEntries; | 189 PRUint32 numCertCacheEntries; |
| 190 PRUint32 certCacheSize; | 190 PRUint32 certCacheSize; |
| 191 | 191 |
| 192 PRUint32 numKeyCacheEntries; | 192 PRUint32 numKeyCacheEntries; |
| 193 PRUint32 keyCacheSize; | 193 PRUint32 keyCacheSize; |
| 194 | 194 |
| 195 PRUint32 numSrvNameCacheEntries; | 195 PRUint32 numSrvNameCacheEntries; |
| 196 PRUint32 srvNameCacheSize; | 196 PRUint32 srvNameCacheSize; |
| 197 | 197 |
| 198 PRUint32» » ssl2Timeout; | 198 PRUint32 ssl2Timeout; |
| 199 PRUint32» » ssl3Timeout; | 199 PRUint32 ssl3Timeout; |
| 200 | 200 |
| 201 PRUint32 numSIDCacheLocksInitialized; | 201 PRUint32 numSIDCacheLocksInitialized; |
| 202 | 202 |
| 203 /* These values are volatile, and are accessed through sharedCache-> */ | 203 /* These values are volatile, and are accessed through sharedCache-> */ |
| 204 PRUint32» » nextCertCacheEntry;» /* certCacheLock protects */ | 204 PRUint32 nextCertCacheEntry; /* certCacheLock protects */ |
| 205 PRBool » stopPolling; | 205 PRBool stopPolling; |
| 206 PRBool» » everInherited; | 206 PRBool everInherited; |
| 207 | 207 |
| 208 /* The private copies of these values are pointers into shared mem */ | 208 /* The private copies of these values are pointers into shared mem */ |
| 209 /* The copies of these values in shared memory are merely offsets */ | 209 /* The copies of these values in shared memory are merely offsets */ |
| 210 sidCacheLock * sidCacheLocks; | 210 sidCacheLock *sidCacheLocks; |
| 211 sidCacheLock * keyCacheLock; | 211 sidCacheLock *keyCacheLock; |
| 212 sidCacheLock * certCacheLock; | 212 sidCacheLock *certCacheLock; |
| 213 sidCacheLock * srvNameCacheLock; | 213 sidCacheLock *srvNameCacheLock; |
| 214 sidCacheSet * sidCacheSets; | 214 sidCacheSet *sidCacheSets; |
| 215 sidCacheEntry * sidCacheData; | 215 sidCacheEntry *sidCacheData; |
| 216 certCacheEntry * certCacheData; | 216 certCacheEntry *certCacheData; |
| 217 SSLWrappedSymWrappingKey * keyCacheData; | 217 SSLWrappedSymWrappingKey *keyCacheData; |
| 218 PRUint8 * ticketKeyNameSuffix; | 218 PRUint8 *ticketKeyNameSuffix; |
| 219 encKeyCacheEntry * ticketEncKey; | 219 encKeyCacheEntry *ticketEncKey; |
| 220 encKeyCacheEntry * ticketMacKey; | 220 encKeyCacheEntry *ticketMacKey; |
| 221 PRUint32 * ticketKeysValid; | 221 PRUint32 *ticketKeysValid; |
| 222 srvNameCacheEntry * srvNameCacheData; | 222 srvNameCacheEntry *srvNameCacheData; |
| 223 | 223 |
| 224 /* Only the private copies of these pointers are valid */ | 224 /* Only the private copies of these pointers are valid */ |
| 225 char * cacheMem; | 225 char *cacheMem; |
| 226 struct cacheDescStr * sharedCache; /* shared copy of this struct */ | 226 struct cacheDescStr *sharedCache; /* shared copy of this struct */ |
| 227 PRFileMap * cacheMemMap; | 227 PRFileMap *cacheMemMap; |
| 228 PRThread * poller; | 228 PRThread *poller; |
| 229 PRUint32 mutexTimeout; | 229 PRUint32 mutexTimeout; |
| 230 PRBool shared; | 230 PRBool shared; |
| 231 }; | 231 }; |
| 232 typedef struct cacheDescStr cacheDesc; | 232 typedef struct cacheDescStr cacheDesc; |
| 233 | 233 |
| 234 static cacheDesc globalCache; | 234 static cacheDesc globalCache; |
| 235 | 235 |
| 236 static const char envVarName[] = { SSL_ENV_VAR_NAME }; | 236 static const char envVarName[] = { SSL_ENV_VAR_NAME }; |
| 237 | 237 |
| 238 static PRBool isMultiProcess = PR_FALSE; | 238 static PRBool isMultiProcess = PR_FALSE; |
| 239 | 239 |
| 240 | 240 #define DEF_SID_CACHE_ENTRIES 10000 |
| 241 #define DEF_SID_CACHE_ENTRIES 10000 | |
| 242 #define DEF_CERT_CACHE_ENTRIES 250 | 241 #define DEF_CERT_CACHE_ENTRIES 250 |
| 243 #define MIN_CERT_CACHE_ENTRIES 125 /* the effective size in old releases. */ | 242 #define MIN_CERT_CACHE_ENTRIES 125 /* the effective size in old releases. */ |
| 244 #define DEF_KEY_CACHE_ENTRIES 250 | 243 #define DEF_KEY_CACHE_ENTRIES 250 |
| 245 #define DEF_NAME_CACHE_ENTRIES 1000 | 244 #define DEF_NAME_CACHE_ENTRIES 1000 |
| 246 | 245 |
| 247 #define SID_CACHE_ENTRIES_PER_SET 128 | 246 #define SID_CACHE_ENTRIES_PER_SET 128 |
| 248 #define SID_ALIGNMENT 16 | 247 #define SID_ALIGNMENT 16 |
| 249 | 248 |
| 250 #define DEF_SSL2_TIMEOUT» 100 /* seconds */ | 249 #define DEF_SSL2_TIMEOUT 100 /* seconds */ |
| 251 #define MAX_SSL2_TIMEOUT» 100 /* seconds */ | 250 #define MAX_SSL2_TIMEOUT 100 /* seconds */ |
| 252 #define MIN_SSL2_TIMEOUT» 5 /* seconds */ | 251 #define MIN_SSL2_TIMEOUT 5 /* seconds */ |
| 253 | 252 |
| 254 #define DEF_SSL3_TIMEOUT 86400L /* 24 hours */ | 253 #define DEF_SSL3_TIMEOUT 86400L /* 24 hours */ |
| 255 #define MAX_SSL3_TIMEOUT 86400L /* 24 hours */ | 254 #define MAX_SSL3_TIMEOUT 86400L /* 24 hours */ |
| 256 #define MIN_SSL3_TIMEOUT 5 /* seconds */ | 255 #define MIN_SSL3_TIMEOUT 5 /* seconds */ |
| 257 | 256 |
| 258 #if defined(AIX) || defined(LINUX) || defined(NETBSD) || defined(OPENBSD) | 257 #if defined(AIX) || defined(LINUX) || defined(NETBSD) || defined(OPENBSD) |
| 259 #define MAX_SID_CACHE_LOCKS 8» /* two FDs per lock */ | 258 #define MAX_SID_CACHE_LOCKS 8 /* two FDs per lock */ |
| 260 #elif defined(OSF1) | 259 #elif defined(OSF1) |
| 261 #define MAX_SID_CACHE_LOCKS 16» /* one FD per lock */ | 260 #define MAX_SID_CACHE_LOCKS 16 /* one FD per lock */ |
| 262 #else | 261 #else |
| 263 #define MAX_SID_CACHE_LOCKS 256 | 262 #define MAX_SID_CACHE_LOCKS 256 |
| 264 #endif | 263 #endif |
| 265 | 264 |
| 266 #define SID_HOWMANY(val, size) (((val) + ((size) - 1)) / (size)) | 265 #define SID_HOWMANY(val, size) (((val) + ((size)-1)) / (size)) |
| 267 #define SID_ROUNDUP(val, size) ((size) * SID_HOWMANY((val), (size))) | 266 #define SID_ROUNDUP(val, size) ((size)*SID_HOWMANY((val), (size))) |
| 268 | |
| 269 | 267 |
| 270 static sslPID myPid; | 268 static sslPID myPid; |
| 271 static PRUint32 ssl_max_sid_cache_locks = MAX_SID_CACHE_LOCKS; | 269 static PRUint32 ssl_max_sid_cache_locks = MAX_SID_CACHE_LOCKS; |
| 272 | 270 |
| 273 /* forward static function declarations */ | 271 /* forward static function declarations */ |
| 274 static PRUint32 SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, | 272 static PRUint32 SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, |
| 275 unsigned nl); | 273 unsigned nl); |
| 276 static SECStatus LaunchLockPoller(cacheDesc *cache); | 274 static SECStatus LaunchLockPoller(cacheDesc *cache); |
| 277 static SECStatus StopLockPoller(cacheDesc *cache); | 275 static SECStatus StopLockPoller(cacheDesc *cache); |
| 278 | 276 |
| 279 | |
| 280 struct inheritanceStr { | 277 struct inheritanceStr { |
| 281 PRUint32 cacheMemSize; | 278 PRUint32 cacheMemSize; |
| 282 PRUint32 fmStrLen; | 279 PRUint32 fmStrLen; |
| 283 }; | 280 }; |
| 284 | 281 |
| 285 typedef struct inheritanceStr inheritance; | 282 typedef struct inheritanceStr inheritance; |
| 286 | 283 |
| 287 #if defined(_WIN32) || defined(XP_OS2) | 284 #if defined(_WIN32) || defined(XP_OS2) |
| 288 | 285 |
| 289 #define DEFAULT_CACHE_DIRECTORY "\\temp" | 286 #define DEFAULT_CACHE_DIRECTORY "\\temp" |
| 290 | 287 |
| 291 #endif /* _win32 */ | 288 #endif /* _win32 */ |
| 292 | 289 |
| 293 #if defined(XP_UNIX) || defined(XP_BEOS) | 290 #if defined(XP_UNIX) || defined(XP_BEOS) |
| 294 | 291 |
| 295 #define DEFAULT_CACHE_DIRECTORY "/tmp" | 292 #define DEFAULT_CACHE_DIRECTORY "/tmp" |
| 296 | 293 |
| 297 #endif /* XP_UNIX || XP_BEOS */ | 294 #endif /* XP_UNIX || XP_BEOS */ |
| 298 | 295 |
| 299 | |
| 300 /************************************************************************/ | 296 /************************************************************************/ |
| 301 | 297 |
| 302 static PRUint32 | 298 static PRUint32 |
| 303 LockSidCacheLock(sidCacheLock *lock, PRUint32 now) | 299 LockSidCacheLock(sidCacheLock *lock, PRUint32 now) |
| 304 { | 300 { |
| 305 SECStatus rv = sslMutex_Lock(&lock->mutex); | 301 SECStatus rv = sslMutex_Lock(&lock->mutex); |
| 306 if (rv != SECSuccess) | 302 if (rv != SECSuccess) |
| 307 » return 0; | 303 return 0; |
| 308 if (!now) | 304 if (!now) |
| 309 » now = ssl_Time(); | 305 now = ssl_Time(); |
| 310 lock->timeStamp = now; | 306 lock->timeStamp = now; |
| 311 lock->pid = myPid; | 307 lock->pid = myPid; |
| 312 return now; | 308 return now; |
| 313 } | 309 } |
| 314 | 310 |
| 315 static SECStatus | 311 static SECStatus |
| 316 UnlockSidCacheLock(sidCacheLock *lock) | 312 UnlockSidCacheLock(sidCacheLock *lock) |
| 317 { | 313 { |
| 318 SECStatus rv; | 314 SECStatus rv; |
| 319 | 315 |
| 320 lock->pid = 0; | 316 lock->pid = 0; |
| 321 rv = sslMutex_Unlock(&lock->mutex); | 317 rv = sslMutex_Unlock(&lock->mutex); |
| 322 return rv; | 318 return rv; |
| 323 } | 319 } |
| 324 | 320 |
| 325 /* returns the value of ssl_Time on success, zero on failure. */ | 321 /* returns the value of ssl_Time on success, zero on failure. */ |
| 326 static PRUint32 | 322 static PRUint32 |
| 327 LockSet(cacheDesc *cache, PRUint32 set, PRUint32 now) | 323 LockSet(cacheDesc *cache, PRUint32 set, PRUint32 now) |
| 328 { | 324 { |
| 329 PRUint32 lockNum = set % cache->numSIDCacheLocks; | 325 PRUint32 lockNum = set % cache->numSIDCacheLocks; |
| 330 sidCacheLock * lock = cache->sidCacheLocks + lockNum; | 326 sidCacheLock *lock = cache->sidCacheLocks + lockNum; |
| 331 | 327 |
| 332 return LockSidCacheLock(lock, now); | 328 return LockSidCacheLock(lock, now); |
| 333 } | 329 } |
| 334 | 330 |
| 335 static SECStatus | 331 static SECStatus |
| 336 UnlockSet(cacheDesc *cache, PRUint32 set) | 332 UnlockSet(cacheDesc *cache, PRUint32 set) |
| 337 { | 333 { |
| 338 PRUint32 lockNum = set % cache->numSIDCacheLocks; | 334 PRUint32 lockNum = set % cache->numSIDCacheLocks; |
| 339 sidCacheLock * lock = cache->sidCacheLocks + lockNum; | 335 sidCacheLock *lock = cache->sidCacheLocks + lockNum; |
| 340 | 336 |
| 341 return UnlockSidCacheLock(lock); | 337 return UnlockSidCacheLock(lock); |
| 342 } | 338 } |
| 343 | 339 |
| 344 /************************************************************************/ | 340 /************************************************************************/ |
| 345 | 341 |
| 346 | |
| 347 /* Put a certificate in the cache. Update the cert index in the sce. | 342 /* Put a certificate in the cache. Update the cert index in the sce. |
| 348 */ | 343 */ |
| 349 static PRUint32 | 344 static PRUint32 |
| 350 CacheCert(cacheDesc * cache, CERTCertificate *cert, sidCacheEntry *sce) | 345 CacheCert(cacheDesc *cache, CERTCertificate *cert, sidCacheEntry *sce) |
| 351 { | 346 { |
| 352 PRUint32 now; | 347 PRUint32 now; |
| 353 certCacheEntry cce; | 348 certCacheEntry cce; |
| 354 | 349 |
| 355 if ((cert->derCert.len > SSL_MAX_CACHED_CERT_LEN) || | 350 if ((cert->derCert.len > SSL_MAX_CACHED_CERT_LEN) || |
| 356 (cert->derCert.len <= 0) || | 351 (cert->derCert.len <= 0) || |
| 357 » (cert->derCert.data == NULL)) { | 352 (cert->derCert.data == NULL)) { |
| 358 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 353 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 359 » return 0; | 354 return 0; |
| 360 } | 355 } |
| 361 | 356 |
| 362 cce.sessionIDLength = sce->sessionIDLength; | 357 cce.sessionIDLength = sce->sessionIDLength; |
| 363 PORT_Memcpy(cce.sessionID, sce->sessionID, cce.sessionIDLength); | 358 PORT_Memcpy(cce.sessionID, sce->sessionID, cce.sessionIDLength); |
| 364 | 359 |
| 365 cce.certLength = cert->derCert.len; | 360 cce.certLength = cert->derCert.len; |
| 366 PORT_Memcpy(cce.cert, cert->derCert.data, cce.certLength); | 361 PORT_Memcpy(cce.cert, cert->derCert.data, cce.certLength); |
| 367 | 362 |
| 368 /* get lock on cert cache */ | 363 /* get lock on cert cache */ |
| 369 now = LockSidCacheLock(cache->certCacheLock, 0); | 364 now = LockSidCacheLock(cache->certCacheLock, 0); |
| 370 if (now) { | 365 if (now) { |
| 371 | 366 |
| 372 » /* Find where to place the next cert cache entry. */ | 367 /* Find where to place the next cert cache entry. */ |
| 373 » cacheDesc * sharedCache = cache->sharedCache; | 368 cacheDesc *sharedCache = cache->sharedCache; |
| 374 » PRUint32 ndx = sharedCache->nextCertCacheEntry; | 369 PRUint32 ndx = sharedCache->nextCertCacheEntry; |
| 375 | 370 |
| 376 » /* write the entry */ | 371 /* write the entry */ |
| 377 » cache->certCacheData[ndx] = cce; | 372 cache->certCacheData[ndx] = cce; |
| 378 | 373 |
| 379 » /* remember where we put it. */ | 374 /* remember where we put it. */ |
| 380 » sce->u.ssl3.certIndex = ndx; | 375 sce->u.ssl3.certIndex = ndx; |
| 381 | 376 |
| 382 » /* update the "next" cache entry index */ | 377 /* update the "next" cache entry index */ |
| 383 » sharedCache->nextCertCacheEntry = | 378 sharedCache->nextCertCacheEntry = |
| 384 » » » » » (ndx + 1) % cache->numCertCacheEntries; | 379 (ndx + 1) % cache->numCertCacheEntries; |
| 385 | 380 |
| 386 » UnlockSidCacheLock(cache->certCacheLock); | 381 UnlockSidCacheLock(cache->certCacheLock); |
| 387 } | 382 } |
| 388 return now; | 383 return now; |
| 389 | |
| 390 } | 384 } |
| 391 | 385 |
| 392 /* Server configuration hash tables need to account the SECITEM.type | 386 /* Server configuration hash tables need to account the SECITEM.type |
| 393 * field as well. These functions accomplish that. */ | 387 * field as well. These functions accomplish that. */ |
| 394 static PLHashNumber | 388 static PLHashNumber |
| 395 Get32BitNameHash(const SECItem *name) | 389 Get32BitNameHash(const SECItem *name) |
| 396 { | 390 { |
| 397 PLHashNumber rv = SECITEM_Hash(name); | 391 PLHashNumber rv = SECITEM_Hash(name); |
| 398 | 392 |
| 399 PRUint8 *rvc = (PRUint8 *)&rv; | 393 PRUint8 *rvc = (PRUint8 *)&rv; |
| 400 rvc[ name->len % sizeof(rv) ] ^= name->type; | 394 rvc[name->len % sizeof(rv)] ^= name->type; |
| 401 | 395 |
| 402 return rv; | 396 return rv; |
| 403 } | 397 } |
| 404 | 398 |
| 405 /* Put a name in the cache. Update the cert index in the sce. | 399 /* Put a name in the cache. Update the cert index in the sce. |
| 406 */ | 400 */ |
| 407 static PRUint32 | 401 static PRUint32 |
| 408 CacheSrvName(cacheDesc * cache, SECItem *name, sidCacheEntry *sce) | 402 CacheSrvName(cacheDesc *cache, SECItem *name, sidCacheEntry *sce) |
| 409 { | 403 { |
| 410 PRUint32 now; | 404 PRUint32 now; |
| 411 PRUint32 ndx; | 405 PRUint32 ndx; |
| 412 srvNameCacheEntry snce; | 406 srvNameCacheEntry snce; |
| 413 | 407 |
| 414 if (!name || name->len <= 0 || | 408 if (!name || name->len <= 0 || |
| 415 name->len > SSL_MAX_DNS_HOST_NAME) { | 409 name->len > SSL_MAX_DNS_HOST_NAME) { |
| 416 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 410 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 417 » return 0; | 411 return 0; |
| 418 } | 412 } |
| 419 | 413 |
| 420 snce.type = name->type; | 414 snce.type = name->type; |
| 421 snce.nameLen = name->len; | 415 snce.nameLen = name->len; |
| 422 PORT_Memcpy(snce.name, name->data, snce.nameLen); | 416 PORT_Memcpy(snce.name, name->data, snce.nameLen); |
| 423 #ifdef NO_PKCS11_BYPASS | 417 #ifdef NO_PKCS11_BYPASS |
| 424 HASH_HashBuf(HASH_AlgSHA256, snce.nameHash, name->data, name->len); | 418 HASH_HashBuf(HASH_AlgSHA256, snce.nameHash, name->data, name->len); |
| 425 #else | 419 #else |
| 426 SHA256_HashBuf(snce.nameHash, (unsigned char*)name->data, | 420 SHA256_HashBuf(snce.nameHash, (unsigned char *)name->data, |
| 427 name->len); | 421 name->len); |
| 428 #endif | 422 #endif |
| 429 /* get index of the next name */ | 423 /* get index of the next name */ |
| 430 ndx = Get32BitNameHash(name); | 424 ndx = Get32BitNameHash(name); |
| 431 /* get lock on cert cache */ | 425 /* get lock on cert cache */ |
| 432 now = LockSidCacheLock(cache->srvNameCacheLock, 0); | 426 now = LockSidCacheLock(cache->srvNameCacheLock, 0); |
| 433 if (now) { | 427 if (now) { |
| 434 if (cache->numSrvNameCacheEntries > 0) { | 428 if (cache->numSrvNameCacheEntries > 0) { |
| 435 /* Fit the index into array */ | 429 /* Fit the index into array */ |
| 436 ndx %= cache->numSrvNameCacheEntries; | 430 ndx %= cache->numSrvNameCacheEntries; |
| 437 /* write the entry */ | 431 /* write the entry */ |
| 438 cache->srvNameCacheData[ndx] = snce; | 432 cache->srvNameCacheData[ndx] = snce; |
| 439 /* remember where we put it. */ | 433 /* remember where we put it. */ |
| 440 sce->u.ssl3.srvNameIndex = ndx; | 434 sce->u.ssl3.srvNameIndex = ndx; |
| 441 /* Copy hash into sid hash */ | 435 /* Copy hash into sid hash */ |
| 442 PORT_Memcpy(sce->u.ssl3.srvNameHash, snce.nameHash, SHA256_LENGTH); | 436 PORT_Memcpy(sce->u.ssl3.srvNameHash, snce.nameHash, SHA256_LENGTH); |
| 443 } | 437 } |
| 444 » UnlockSidCacheLock(cache->srvNameCacheLock); | 438 UnlockSidCacheLock(cache->srvNameCacheLock); |
| 445 } | 439 } |
| 446 return now; | 440 return now; |
| 447 } | 441 } |
| 448 | 442 |
| 449 /* | 443 /* |
| 450 ** Convert local SID to shared memory one | 444 ** Convert local SID to shared memory one |
| 451 */ | 445 */ |
| 452 static void | 446 static void |
| 453 ConvertFromSID(sidCacheEntry *to, sslSessionID *from) | 447 ConvertFromSID(sidCacheEntry *to, sslSessionID *from) |
| 454 { | 448 { |
| 455 to->valid = 1; | 449 to->valid = 1; |
| 456 to->version = from->version; | 450 to->version = from->version; |
| 457 to->addr = from->addr; | 451 to->addr = from->addr; |
| 458 to->creationTime = from->creationTime; | 452 to->creationTime = from->creationTime; |
| 459 to->lastAccessTime = from->lastAccessTime; | 453 to->lastAccessTime = from->lastAccessTime; |
| 460 to->expirationTime = from->expirationTime; | 454 to->expirationTime = from->expirationTime; |
| 461 to->authAlgorithm» = from->authAlgorithm; | 455 to->authAlgorithm = from->authAlgorithm; |
| 462 to->authKeyBits» = from->authKeyBits; | 456 to->authKeyBits = from->authKeyBits; |
| 463 to->keaType»» = from->keaType; | 457 to->keaType = from->keaType; |
| 464 to->keaKeyBits» = from->keaKeyBits; | 458 to->keaKeyBits = from->keaKeyBits; |
| 465 | 459 |
| 466 if (from->version < SSL_LIBRARY_VERSION_3_0) { | 460 if (from->version < SSL_LIBRARY_VERSION_3_0) { |
| 467 » if ((from->u.ssl2.masterKey.len > SSL_MAX_MASTER_KEY_BYTES) || | 461 if ((from->u.ssl2.masterKey.len > SSL_MAX_MASTER_KEY_BYTES) || |
| 468 » (from->u.ssl2.cipherArg.len > SSL_MAX_CYPHER_ARG_BYTES)) { | 462 (from->u.ssl2.cipherArg.len > SSL_MAX_CYPHER_ARG_BYTES)) { |
| 469 » SSL_DBG(("%d: SSL: masterKeyLen=%d cipherArgLen=%d", | 463 SSL_DBG(("%d: SSL: masterKeyLen=%d cipherArgLen=%d", |
| 470 » » myPid, from->u.ssl2.masterKey.len, | 464 myPid, from->u.ssl2.masterKey.len, |
| 471 » » from->u.ssl2.cipherArg.len)); | 465 from->u.ssl2.cipherArg.len)); |
| 472 » to->valid = 0; | 466 to->valid = 0; |
| 473 » return; | 467 return; |
| 474 » } | 468 } |
| 475 | 469 |
| 476 » to->u.ssl2.cipherType = from->u.ssl2.cipherType; | 470 to->u.ssl2.cipherType = from->u.ssl2.cipherType; |
| 477 » to->u.ssl2.masterKeyLen = from->u.ssl2.masterKey.len; | 471 to->u.ssl2.masterKeyLen = from->u.ssl2.masterKey.len; |
| 478 » to->u.ssl2.cipherArgLen = from->u.ssl2.cipherArg.len; | 472 to->u.ssl2.cipherArgLen = from->u.ssl2.cipherArg.len; |
| 479 » to->u.ssl2.keyBits = from->u.ssl2.keyBits; | 473 to->u.ssl2.keyBits = from->u.ssl2.keyBits; |
| 480 » to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits; | 474 to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits; |
| 481 » to->sessionIDLength = SSL2_SESSIONID_BYTES; | 475 to->sessionIDLength = SSL2_SESSIONID_BYTES; |
| 482 » PORT_Memcpy(to->sessionID, from->u.ssl2.sessionID, SSL2_SESSIONID_BYTES)
; | 476 PORT_Memcpy(to->sessionID, from->u.ssl2.sessionID, SSL2_SESSIONID_BYTES)
; |
| 483 » PORT_Memcpy(to->u.ssl2.masterKey, from->u.ssl2.masterKey.data, | 477 PORT_Memcpy(to->u.ssl2.masterKey, from->u.ssl2.masterKey.data, |
| 484 » » from->u.ssl2.masterKey.len); | 478 from->u.ssl2.masterKey.len); |
| 485 » PORT_Memcpy(to->u.ssl2.cipherArg, from->u.ssl2.cipherArg.data, | 479 PORT_Memcpy(to->u.ssl2.cipherArg, from->u.ssl2.cipherArg.data, |
| 486 » » from->u.ssl2.cipherArg.len); | 480 from->u.ssl2.cipherArg.len); |
| 487 #ifdef DEBUG | 481 #ifdef DEBUG |
| 488 » PORT_Memset(to->u.ssl2.masterKey+from->u.ssl2.masterKey.len, 0, | 482 PORT_Memset(to->u.ssl2.masterKey + from->u.ssl2.masterKey.len, 0, |
| 489 » » sizeof(to->u.ssl2.masterKey) - from->u.ssl2.masterKey.len); | 483 sizeof(to->u.ssl2.masterKey) - from->u.ssl2.masterKey.len); |
| 490 » PORT_Memset(to->u.ssl2.cipherArg+from->u.ssl2.cipherArg.len, 0, | 484 PORT_Memset(to->u.ssl2.cipherArg + from->u.ssl2.cipherArg.len, 0, |
| 491 » » sizeof(to->u.ssl2.cipherArg) - from->u.ssl2.cipherArg.len); | 485 sizeof(to->u.ssl2.cipherArg) - from->u.ssl2.cipherArg.len); |
| 492 #endif | 486 #endif |
| 493 » SSL_TRC(8, ("%d: SSL: ConvertSID: masterKeyLen=%d cipherArgLen=%d " | 487 SSL_TRC(8, ("%d: SSL: ConvertSID: masterKeyLen=%d cipherArgLen=%d " |
| 494 » » "time=%d addr=0x%08x%08x%08x%08x cipherType=%d", myPid, | 488 "time=%d addr=0x%08x%08x%08x%08x cipherType=%d", |
| 495 » » to->u.ssl2.masterKeyLen, to->u.ssl2.cipherArgLen, | 489 myPid, |
| 496 » » to->creationTime, to->addr.pr_s6_addr32[0], | 490 to->u.ssl2.masterKeyLen, to->u.ssl2.cipherArgLen, |
| 497 » » to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2], | 491 to->creationTime, to->addr.pr_s6_addr32[0], |
| 498 » » to->addr.pr_s6_addr32[3], to->u.ssl2.cipherType)); | 492 to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2], |
| 493 to->addr.pr_s6_addr32[3], to->u.ssl2.cipherType)); |
| 499 } else { | 494 } else { |
| 500 » /* This is an SSL v3 session */ | 495 /* This is an SSL v3 session */ |
| 501 | 496 |
| 502 » to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite; | 497 to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite; |
| 503 » to->u.ssl3.compression = (PRUint16)from->u.ssl3.compression; | 498 to->u.ssl3.compression = (PRUint16)from->u.ssl3.compression; |
| 504 » to->u.ssl3.keys = from->u.ssl3.keys; | 499 to->u.ssl3.keys = from->u.ssl3.keys; |
| 505 » to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech; | 500 to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech; |
| 506 » to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType; | 501 to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType; |
| 507 » to->sessionIDLength = from->u.ssl3.sessionIDLength; | 502 to->sessionIDLength = from->u.ssl3.sessionIDLength; |
| 508 » to->u.ssl3.certIndex = -1; | 503 to->u.ssl3.certIndex = -1; |
| 509 » to->u.ssl3.srvNameIndex = -1; | 504 to->u.ssl3.srvNameIndex = -1; |
| 510 » PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID, | 505 PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID, |
| 511 » » to->sessionIDLength); | 506 to->sessionIDLength); |
| 512 | 507 |
| 513 » SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x " | 508 SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x " |
| 514 » "cipherSuite=%d", | 509 "cipherSuite=%d", |
| 515 » » myPid, to->creationTime, to->addr.pr_s6_addr32[0], | 510 myPid, to->creationTime, to->addr.pr_s6_addr32[0], |
| 516 » » to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2], | 511 to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2], |
| 517 » » to->addr.pr_s6_addr32[3], to->u.ssl3.cipherSuite)); | 512 to->addr.pr_s6_addr32[3], to->u.ssl3.cipherSuite)); |
| 518 } | 513 } |
| 519 } | 514 } |
| 520 | 515 |
| 521 /* | 516 /* |
| 522 ** Convert shared memory cache-entry to local memory based one | 517 ** Convert shared memory cache-entry to local memory based one |
| 523 ** This is only called from ServerSessionIDLookup(). | 518 ** This is only called from ServerSessionIDLookup(). |
| 524 */ | 519 */ |
| 525 static sslSessionID * | 520 static sslSessionID * |
| 526 ConvertToSID(sidCacheEntry * from, | 521 ConvertToSID(sidCacheEntry *from, |
| 527 certCacheEntry * pcce, | 522 certCacheEntry *pcce, |
| 528 srvNameCacheEntry *psnce, | 523 srvNameCacheEntry *psnce, |
| 529 CERTCertDBHandle * dbHandle) | 524 CERTCertDBHandle *dbHandle) |
| 530 { | 525 { |
| 531 sslSessionID *to; | 526 sslSessionID *to; |
| 532 PRUint16 version = from->version; | 527 PRUint16 version = from->version; |
| 533 | 528 |
| 534 to = PORT_ZNew(sslSessionID); | 529 to = PORT_ZNew(sslSessionID); |
| 535 if (!to) { | 530 if (!to) { |
| 536 » return 0; | 531 return 0; |
| 537 } | 532 } |
| 538 | 533 |
| 539 if (version < SSL_LIBRARY_VERSION_3_0) { | 534 if (version < SSL_LIBRARY_VERSION_3_0) { |
| 540 » /* This is an SSL v2 session */ | 535 /* This is an SSL v2 session */ |
| 541 » to->u.ssl2.masterKey.data = | 536 to->u.ssl2.masterKey.data = |
| 542 » (unsigned char*) PORT_Alloc(from->u.ssl2.masterKeyLen); | 537 (unsigned char *)PORT_Alloc(from->u.ssl2.masterKeyLen); |
| 543 » if (!to->u.ssl2.masterKey.data) { | 538 if (!to->u.ssl2.masterKey.data) { |
| 544 » goto loser; | 539 goto loser; |
| 545 » } | 540 } |
| 546 » if (from->u.ssl2.cipherArgLen) { | 541 if (from->u.ssl2.cipherArgLen) { |
| 547 » to->u.ssl2.cipherArg.data = | 542 to->u.ssl2.cipherArg.data = |
| 548 » » (unsigned char*)PORT_Alloc(from->u.ssl2.cipherArgLen); | 543 (unsigned char *)PORT_Alloc(from->u.ssl2.cipherArgLen); |
| 549 » if (!to->u.ssl2.cipherArg.data) { | 544 if (!to->u.ssl2.cipherArg.data) { |
| 550 » » goto loser; | 545 goto loser; |
| 551 » } | 546 } |
| 552 » PORT_Memcpy(to->u.ssl2.cipherArg.data, from->u.ssl2.cipherArg, | 547 PORT_Memcpy(to->u.ssl2.cipherArg.data, from->u.ssl2.cipherArg, |
| 553 » » from->u.ssl2.cipherArgLen); | 548 from->u.ssl2.cipherArgLen); |
| 554 » } | 549 } |
| 555 | 550 |
| 556 » to->u.ssl2.cipherType = from->u.ssl2.cipherType; | 551 to->u.ssl2.cipherType = from->u.ssl2.cipherType; |
| 557 » to->u.ssl2.masterKey.len = from->u.ssl2.masterKeyLen; | 552 to->u.ssl2.masterKey.len = from->u.ssl2.masterKeyLen; |
| 558 » to->u.ssl2.cipherArg.len = from->u.ssl2.cipherArgLen; | 553 to->u.ssl2.cipherArg.len = from->u.ssl2.cipherArgLen; |
| 559 » to->u.ssl2.keyBits = from->u.ssl2.keyBits; | 554 to->u.ssl2.keyBits = from->u.ssl2.keyBits; |
| 560 » to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits; | 555 to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits; |
| 561 /*» to->sessionIDLength = SSL2_SESSIONID_BYTES; */ | 556 /* to->sessionIDLength = SSL2_SESSIONID_BYTES; */ |
| 562 » PORT_Memcpy(to->u.ssl2.sessionID, from->sessionID, SSL2_SESSIONID_BYTES)
; | 557 PORT_Memcpy(to->u.ssl2.sessionID, from->sessionID, SSL2_SESSIONID_BYTES)
; |
| 563 » PORT_Memcpy(to->u.ssl2.masterKey.data, from->u.ssl2.masterKey, | 558 PORT_Memcpy(to->u.ssl2.masterKey.data, from->u.ssl2.masterKey, |
| 564 » » from->u.ssl2.masterKeyLen); | 559 from->u.ssl2.masterKeyLen); |
| 565 | 560 |
| 566 » SSL_TRC(8, ("%d: SSL: ConvertToSID: masterKeyLen=%d cipherArgLen=%d " | 561 SSL_TRC(8, ("%d: SSL: ConvertToSID: masterKeyLen=%d cipherArgLen=%d " |
| 567 » » "time=%d addr=0x%08x%08x%08x%08x cipherType=%d", | 562 "time=%d addr=0x%08x%08x%08x%08x cipherType=%d", |
| 568 » » myPid, to->u.ssl2.masterKey.len, | 563 myPid, to->u.ssl2.masterKey.len, |
| 569 » » to->u.ssl2.cipherArg.len, to->creationTime, | 564 to->u.ssl2.cipherArg.len, to->creationTime, |
| 570 » » to->addr.pr_s6_addr32[0], to->addr.pr_s6_addr32[1], | 565 to->addr.pr_s6_addr32[0], to->addr.pr_s6_addr32[1], |
| 571 » » to->addr.pr_s6_addr32[2], to->addr.pr_s6_addr32[3], | 566 to->addr.pr_s6_addr32[2], to->addr.pr_s6_addr32[3], |
| 572 » » to->u.ssl2.cipherType)); | 567 to->u.ssl2.cipherType)); |
| 573 } else { | 568 } else { |
| 574 » /* This is an SSL v3 session */ | 569 /* This is an SSL v3 session */ |
| 575 | 570 |
| 576 » to->u.ssl3.sessionIDLength = from->sessionIDLength; | 571 to->u.ssl3.sessionIDLength = from->sessionIDLength; |
| 577 » to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite; | 572 to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite; |
| 578 » to->u.ssl3.compression = (SSLCompressionMethod)from->u.ssl3.compres
sion; | 573 to->u.ssl3.compression = (SSLCompressionMethod)from->u.ssl3.compression; |
| 579 » to->u.ssl3.keys = from->u.ssl3.keys; | 574 to->u.ssl3.keys = from->u.ssl3.keys; |
| 580 » to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech; | 575 to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech; |
| 581 » to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType; | 576 to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType; |
| 582 » if (from->u.ssl3.srvNameIndex != -1 && psnce) { | 577 if (from->u.ssl3.srvNameIndex != -1 && psnce) { |
| 583 SECItem name; | 578 SECItem name; |
| 584 SECStatus rv; | 579 SECStatus rv; |
| 585 name.type = psnce->type; | 580 name.type = psnce->type; |
| 586 name.len = psnce->nameLen; | 581 name.len = psnce->nameLen; |
| 587 name.data = psnce->name; | 582 name.data = psnce->name; |
| 588 rv = SECITEM_CopyItem(NULL, &to->u.ssl3.srvName, &name); | 583 rv = SECITEM_CopyItem(NULL, &to->u.ssl3.srvName, &name); |
| 589 if (rv != SECSuccess) { | 584 if (rv != SECSuccess) { |
| 590 goto loser; | 585 goto loser; |
| 591 } | 586 } |
| 592 } | 587 } |
| 593 | 588 |
| 594 » PORT_Memcpy(to->u.ssl3.sessionID, from->sessionID, from->sessionIDLength
); | 589 PORT_Memcpy(to->u.ssl3.sessionID, from->sessionID, from->sessionIDLength
); |
| 595 | 590 |
| 596 » /* the portions of the SID that are only restored on the client | 591 /* the portions of the SID that are only restored on the client |
| 597 » * are set to invalid values on the server. | 592 * are set to invalid values on the server. |
| 598 » */ | 593 */ |
| 599 » to->u.ssl3.clientWriteKey = NULL; | 594 to->u.ssl3.clientWriteKey = NULL; |
| 600 » to->u.ssl3.serverWriteKey = NULL; | 595 to->u.ssl3.serverWriteKey = NULL; |
| 601 | 596 |
| 602 » to->urlSvrName = NULL; | 597 to->urlSvrName = NULL; |
| 603 | 598 |
| 604 » to->u.ssl3.masterModuleID = (SECMODModuleID)-1; /* invalid value */ | 599 to->u.ssl3.masterModuleID = (SECMODModuleID)-1; /* invalid value */ |
| 605 » to->u.ssl3.masterSlotID = (CK_SLOT_ID)-1; /* invalid value */ | 600 to->u.ssl3.masterSlotID = (CK_SLOT_ID)-1; /* invalid value */ |
| 606 » to->u.ssl3.masterWrapIndex = 0; | 601 to->u.ssl3.masterWrapIndex = 0; |
| 607 » to->u.ssl3.masterWrapSeries = 0; | 602 to->u.ssl3.masterWrapSeries = 0; |
| 608 » to->u.ssl3.masterValid = PR_FALSE; | 603 to->u.ssl3.masterValid = PR_FALSE; |
| 609 | 604 |
| 610 » to->u.ssl3.clAuthModuleID = (SECMODModuleID)-1; /* invalid value */ | 605 to->u.ssl3.clAuthModuleID = (SECMODModuleID)-1; /* invalid value */ |
| 611 » to->u.ssl3.clAuthSlotID = (CK_SLOT_ID)-1; /* invalid value */ | 606 to->u.ssl3.clAuthSlotID = (CK_SLOT_ID)-1; /* invalid value */ |
| 612 » to->u.ssl3.clAuthSeries = 0; | 607 to->u.ssl3.clAuthSeries = 0; |
| 613 » to->u.ssl3.clAuthValid = PR_FALSE; | 608 to->u.ssl3.clAuthValid = PR_FALSE; |
| 614 | 609 |
| 615 » if (from->u.ssl3.certIndex != -1 && pcce) { | 610 if (from->u.ssl3.certIndex != -1 && pcce) { |
| 616 » SECItem derCert; | 611 SECItem derCert; |
| 617 | 612 |
| 618 » derCert.len = pcce->certLength; | 613 derCert.len = pcce->certLength; |
| 619 » derCert.data = pcce->cert; | 614 derCert.data = pcce->cert; |
| 620 | 615 |
| 621 » to->peerCert = CERT_NewTempCertificate(dbHandle, &derCert, NULL, | 616 to->peerCert = CERT_NewTempCertificate(dbHandle, &derCert, NULL, |
| 622 » » » » » PR_FALSE, PR_TRUE); | 617 PR_FALSE, PR_TRUE); |
| 623 » if (to->peerCert == NULL) | 618 if (to->peerCert == NULL) |
| 624 » » goto loser; | 619 goto loser; |
| 625 » } | 620 } |
| 626 } | 621 } |
| 627 | 622 |
| 628 to->version = from->version; | 623 to->version = from->version; |
| 629 to->creationTime = from->creationTime; | 624 to->creationTime = from->creationTime; |
| 630 to->lastAccessTime = from->lastAccessTime; | 625 to->lastAccessTime = from->lastAccessTime; |
| 631 to->expirationTime = from->expirationTime; | 626 to->expirationTime = from->expirationTime; |
| 632 to->cached = in_server_cache; | 627 to->cached = in_server_cache; |
| 633 to->addr = from->addr; | 628 to->addr = from->addr; |
| 634 to->references = 1; | 629 to->references = 1; |
| 635 to->authAlgorithm» = from->authAlgorithm; | 630 to->authAlgorithm = from->authAlgorithm; |
| 636 to->authKeyBits» = from->authKeyBits; | 631 to->authKeyBits = from->authKeyBits; |
| 637 to->keaType»» = from->keaType; | 632 to->keaType = from->keaType; |
| 638 to->keaKeyBits» = from->keaKeyBits; | 633 to->keaKeyBits = from->keaKeyBits; |
| 639 | 634 |
| 640 return to; | 635 return to; |
| 641 | 636 |
| 642 loser: | 637 loser: |
| 643 if (to) { | 638 if (to) { |
| 644 » if (version < SSL_LIBRARY_VERSION_3_0) { | 639 if (version < SSL_LIBRARY_VERSION_3_0) { |
| 645 » if (to->u.ssl2.masterKey.data) | 640 if (to->u.ssl2.masterKey.data) |
| 646 » » PORT_Free(to->u.ssl2.masterKey.data); | 641 PORT_Free(to->u.ssl2.masterKey.data); |
| 647 » if (to->u.ssl2.cipherArg.data) | 642 if (to->u.ssl2.cipherArg.data) |
| 648 » » PORT_Free(to->u.ssl2.cipherArg.data); | 643 PORT_Free(to->u.ssl2.cipherArg.data); |
| 649 » } else { | 644 } else { |
| 650 SECITEM_FreeItem(&to->u.ssl3.srvName, PR_FALSE); | 645 SECITEM_FreeItem(&to->u.ssl3.srvName, PR_FALSE); |
| 651 } | 646 } |
| 652 » PORT_Free(to); | 647 PORT_Free(to); |
| 653 } | 648 } |
| 654 return NULL; | 649 return NULL; |
| 655 } | 650 } |
| 656 | 651 |
| 657 | |
| 658 | |
| 659 /* | 652 /* |
| 660 ** Perform some mumbo jumbo on the ip-address and the session-id value to | 653 ** Perform some mumbo jumbo on the ip-address and the session-id value to |
| 661 ** compute a hash value. | 654 ** compute a hash value. |
| 662 */ | 655 */ |
| 663 static PRUint32 | 656 static PRUint32 |
| 664 SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, unsigned nl) | 657 SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, unsigned nl) |
| 665 { | 658 { |
| 666 PRUint32 rv; | 659 PRUint32 rv; |
| 667 PRUint32 x[8]; | 660 PRUint32 x[8]; |
| 668 | 661 |
| 669 memset(x, 0, sizeof x); | 662 memset(x, 0, sizeof x); |
| 670 if (nl > sizeof x) | 663 if (nl > sizeof x) |
| 671 » nl = sizeof x; | 664 nl = sizeof x; |
| 672 memcpy(x, s, nl); | 665 memcpy(x, s, nl); |
| 673 | 666 |
| 674 rv = (addr->pr_s6_addr32[0] ^ addr->pr_s6_addr32[1] ^ | 667 rv = (addr->pr_s6_addr32[0] ^ addr->pr_s6_addr32[1] ^ |
| 675 » addr->pr_s6_addr32[2] ^ addr->pr_s6_addr32[3] ^ | 668 addr->pr_s6_addr32[2] ^ addr->pr_s6_addr32[3] ^ |
| 676 x[0] ^ x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7]) | 669 x[0] ^ x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7]) % |
| 677 » % cache->numSIDCacheSets; | 670 cache->numSIDCacheSets; |
| 678 return rv; | 671 return rv; |
| 679 } | 672 } |
| 680 | 673 |
| 681 | |
| 682 | |
| 683 /* | 674 /* |
| 684 ** Look something up in the cache. This will invalidate old entries | 675 ** Look something up in the cache. This will invalidate old entries |
| 685 ** in the process. Caller has locked the cache set! | 676 ** in the process. Caller has locked the cache set! |
| 686 ** Returns PR_TRUE if found a valid match. PR_FALSE otherwise. | 677 ** Returns PR_TRUE if found a valid match. PR_FALSE otherwise. |
| 687 */ | 678 */ |
| 688 static sidCacheEntry * | 679 static sidCacheEntry * |
| 689 FindSID(cacheDesc *cache, PRUint32 setNum, PRUint32 now, | 680 FindSID(cacheDesc *cache, PRUint32 setNum, PRUint32 now, |
| 690 const PRIPv6Addr *addr, unsigned char *sessionID, | 681 const PRIPv6Addr *addr, unsigned char *sessionID, |
| 691 » unsigned sessionIDLength) | 682 unsigned sessionIDLength) |
| 692 { | 683 { |
| 693 PRUint32 ndx = cache->sidCacheSets[setNum].next; | 684 PRUint32 ndx = cache->sidCacheSets[setNum].next; |
| 694 int i; | 685 int i; |
| 695 | 686 |
| 696 sidCacheEntry * set = cache->sidCacheData + | 687 sidCacheEntry *set = cache->sidCacheData + |
| 697 » » » (setNum * SID_CACHE_ENTRIES_PER_SET); | 688 (setNum * SID_CACHE_ENTRIES_PER_SET); |
| 698 | 689 |
| 699 for (i = SID_CACHE_ENTRIES_PER_SET; i > 0; --i) { | 690 for (i = SID_CACHE_ENTRIES_PER_SET; i > 0; --i) { |
| 700 » sidCacheEntry * sce; | 691 sidCacheEntry *sce; |
| 701 | 692 |
| 702 » ndx = (ndx - 1) % SID_CACHE_ENTRIES_PER_SET; | 693 ndx = (ndx - 1) % SID_CACHE_ENTRIES_PER_SET; |
| 703 » sce = set + ndx; | 694 sce = set + ndx; |
| 704 | 695 |
| 705 » if (!sce->valid) | 696 if (!sce->valid) |
| 706 » continue; | 697 continue; |
| 707 | 698 |
| 708 » if (now > sce->expirationTime) { | 699 if (now > sce->expirationTime) { |
| 709 » /* SessionID has timed out. Invalidate the entry. */ | 700 /* SessionID has timed out. Invalidate the entry. */ |
| 710 » SSL_TRC(7, ("%d: timed out sid entry addr=%08x%08x%08x%08x now=%x " | 701 SSL_TRC(7, ("%d: timed out sid entry addr=%08x%08x%08x%08x now=%x " |
| 711 » » » "time+=%x", | 702 "time+=%x", |
| 712 » » » myPid, sce->addr.pr_s6_addr32[0], | 703 myPid, sce->addr.pr_s6_addr32[0], |
| 713 » » » sce->addr.pr_s6_addr32[1], sce->addr.pr_s6_addr32[2], | 704 sce->addr.pr_s6_addr32[1], sce->addr.pr_s6_addr32[2], |
| 714 » » » sce->addr.pr_s6_addr32[3], now, | 705 sce->addr.pr_s6_addr32[3], now, |
| 715 » » » sce->expirationTime )); | 706 sce->expirationTime)); |
| 716 » sce->valid = 0; | 707 sce->valid = 0; |
| 717 » continue; | 708 continue; |
| 718 » } | 709 } |
| 719 | 710 |
| 720 » /* | 711 /* |
| 721 » ** Next, examine specific session-id/addr data to see if the cache | 712 ** Next, examine specific session-id/addr data to see if the cache |
| 722 » ** entry matches our addr+session-id value | 713 ** entry matches our addr+session-id value |
| 723 » */ | 714 */ |
| 724 » if (sessionIDLength == sce->sessionIDLength && | 715 if (sessionIDLength == sce->sessionIDLength && |
| 725 » !memcmp(&sce->addr, addr, sizeof(PRIPv6Addr)) && | 716 !memcmp(&sce->addr, addr, sizeof(PRIPv6Addr)) && |
| 726 » !memcmp(sce->sessionID, sessionID, sessionIDLength)) { | 717 !memcmp(sce->sessionID, sessionID, sessionIDLength)) { |
| 727 » /* Found it */ | 718 /* Found it */ |
| 728 » return sce; | 719 return sce; |
| 729 » } | 720 } |
| 730 } | 721 } |
| 731 | 722 |
| 732 PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND); | 723 PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND); |
| 733 return NULL; | 724 return NULL; |
| 734 } | 725 } |
| 735 | 726 |
| 736 /************************************************************************/ | 727 /************************************************************************/ |
| 737 | 728 |
| 738 /* This is the primary function for finding entries in the server's sid cache. | 729 /* This is the primary function for finding entries in the server's sid cache. |
| 739 * Although it is static, this function is called via the global function | 730 * Although it is static, this function is called via the global function |
| 740 * pointer ssl_sid_lookup. | 731 * pointer ssl_sid_lookup. |
| 741 */ | 732 */ |
| 742 static sslSessionID * | 733 static sslSessionID * |
| 743 ServerSessionIDLookup(const PRIPv6Addr *addr, | 734 ServerSessionIDLookup(const PRIPv6Addr *addr, |
| 744 » » » unsigned char *sessionID, | 735 unsigned char *sessionID, |
| 745 » » » unsigned int sessionIDLength, | 736 unsigned int sessionIDLength, |
| 746 CERTCertDBHandle * dbHandle) | 737 CERTCertDBHandle *dbHandle) |
| 747 { | 738 { |
| 748 sslSessionID * sid = 0; | 739 sslSessionID *sid = 0; |
| 749 sidCacheEntry * psce; | 740 sidCacheEntry *psce; |
| 750 certCacheEntry *pcce = 0; | 741 certCacheEntry *pcce = 0; |
| 751 srvNameCacheEntry *psnce = 0; | 742 srvNameCacheEntry *psnce = 0; |
| 752 cacheDesc * cache = &globalCache; | 743 cacheDesc *cache = &globalCache; |
| 753 PRUint32 now; | 744 PRUint32 now; |
| 754 PRUint32 set; | 745 PRUint32 set; |
| 755 PRInt32 cndx; | 746 PRInt32 cndx; |
| 756 sidCacheEntry sce; | 747 sidCacheEntry sce; |
| 757 certCacheEntry cce; | 748 certCacheEntry cce; |
| 758 srvNameCacheEntry snce; | 749 srvNameCacheEntry snce; |
| 759 | 750 |
| 760 set = SIDindex(cache, addr, sessionID, sessionIDLength); | 751 set = SIDindex(cache, addr, sessionID, sessionIDLength); |
| 761 now = LockSet(cache, set, 0); | 752 now = LockSet(cache, set, 0); |
| 762 if (!now) | 753 if (!now) |
| 763 » return NULL; | 754 return NULL; |
| 764 | 755 |
| 765 psce = FindSID(cache, set, now, addr, sessionID, sessionIDLength); | 756 psce = FindSID(cache, set, now, addr, sessionID, sessionIDLength); |
| 766 if (psce) { | 757 if (psce) { |
| 767 » if (psce->version >= SSL_LIBRARY_VERSION_3_0) { | 758 if (psce->version >= SSL_LIBRARY_VERSION_3_0) { |
| 768 » if ((cndx = psce->u.ssl3.certIndex) != -1) { | 759 if ((cndx = psce->u.ssl3.certIndex) != -1) { |
| 769 | 760 |
| 770 PRUint32 gotLock = LockSidCacheLock(cache->certCacheLock, now); | 761 PRUint32 gotLock = LockSidCacheLock(cache->certCacheLock, now); |
| 771 if (gotLock) { | 762 if (gotLock) { |
| 772 pcce = &cache->certCacheData[cndx]; | 763 pcce = &cache->certCacheData[cndx]; |
| 773 | 764 |
| 774 /* See if the cert's session ID matches the sce cache. */ | 765 /* See if the cert's session ID matches the sce cache. */ |
| 775 if ((pcce->sessionIDLength == psce->sessionIDLength) && | 766 if ((pcce->sessionIDLength == psce->sessionIDLength) && |
| 776 !PORT_Memcmp(pcce->sessionID, psce->sessionID, | 767 !PORT_Memcmp(pcce->sessionID, psce->sessionID, |
| 777 pcce->sessionIDLength)) { | 768 pcce->sessionIDLength)) { |
| 778 cce = *pcce; | 769 cce = *pcce; |
| 779 } else { | 770 } else { |
| 780 /* The cert doesen't match the SID cache entry, | 771 /* The cert doesen't match the SID cache entry, |
| 781 ** so invalidate the SID cache entry. | 772 ** so invalidate the SID cache entry. |
| 782 */ | 773 */ |
| 783 psce->valid = 0; | 774 psce->valid = 0; |
| 784 psce = 0; | 775 psce = 0; |
| 785 pcce = 0; | 776 pcce = 0; |
| 786 } | 777 } |
| 787 UnlockSidCacheLock(cache->certCacheLock); | 778 UnlockSidCacheLock(cache->certCacheLock); |
| 788 } else { | 779 } else { |
| 789 /* what the ??. Didn't get the cert cache lock. | 780 /* what the ??. Didn't get the cert cache lock. |
| 790 ** Don't invalidate the SID cache entry, but don't find it. | 781 ** Don't invalidate the SID cache entry, but don't find it. |
| 791 */ | 782 */ |
| 792 PORT_Assert(!("Didn't get cert Cache Lock!")); | 783 PORT_Assert(!("Didn't get cert Cache Lock!")); |
| 793 psce = 0; | 784 psce = 0; |
| 794 pcce = 0; | 785 pcce = 0; |
| 795 } | 786 } |
| 796 } | 787 } |
| 797 if (psce && ((cndx = psce->u.ssl3.srvNameIndex) != -1)) { | 788 if (psce && ((cndx = psce->u.ssl3.srvNameIndex) != -1)) { |
| 798 PRUint32 gotLock = LockSidCacheLock(cache->srvNameCacheLock, | 789 PRUint32 gotLock = LockSidCacheLock(cache->srvNameCacheLock, |
| 799 now); | 790 now); |
| 800 if (gotLock) { | 791 if (gotLock) { |
| 801 psnce = &cache->srvNameCacheData[cndx]; | 792 psnce = &cache->srvNameCacheData[cndx]; |
| 802 | 793 |
| 803 if (!PORT_Memcmp(psnce->nameHash, psce->u.ssl3.srvNameHash, | 794 if (!PORT_Memcmp(psnce->nameHash, psce->u.ssl3.srvNameHash, |
| 804 SHA256_LENGTH)) { | 795 SHA256_LENGTH)) { |
| 805 snce = *psnce; | 796 snce = *psnce; |
| 806 } else { | 797 } else { |
| 807 /* The name doesen't match the SID cache entry, | 798 /* The name doesen't match the SID cache entry, |
| 808 ** so invalidate the SID cache entry. | 799 ** so invalidate the SID cache entry. |
| 809 */ | 800 */ |
| 810 psce->valid = 0; | 801 psce->valid = 0; |
| 811 psce = 0; | 802 psce = 0; |
| 812 psnce = 0; | 803 psnce = 0; |
| 813 } | 804 } |
| 814 UnlockSidCacheLock(cache->srvNameCacheLock); | 805 UnlockSidCacheLock(cache->srvNameCacheLock); |
| 815 } else { | 806 } else { |
| 816 /* what the ??. Didn't get the cert cache lock. | 807 /* what the ??. Didn't get the cert cache lock. |
| 817 ** Don't invalidate the SID cache entry, but don't find it. | 808 ** Don't invalidate the SID cache entry, but don't find it. |
| 818 */ | 809 */ |
| 819 PORT_Assert(!("Didn't get name Cache Lock!")); | 810 PORT_Assert(!("Didn't get name Cache Lock!")); |
| 820 psce = 0; | 811 psce = 0; |
| 821 psnce = 0; | 812 psnce = 0; |
| 822 } | 813 } |
| 823 | |
| 824 } | 814 } |
| 825 } | 815 } |
| 826 » if (psce) { | 816 if (psce) { |
| 827 » psce->lastAccessTime = now; | 817 psce->lastAccessTime = now; |
| 828 » sce = *psce;» /* grab a copy while holding the lock */ | 818 sce = *psce; /* grab a copy while holding the lock */ |
| 829 » } | 819 } |
| 830 } | 820 } |
| 831 UnlockSet(cache, set); | 821 UnlockSet(cache, set); |
| 832 if (psce) { | 822 if (psce) { |
| 833 » /* sce conains a copy of the cache entry. | 823 /* sce conains a copy of the cache entry. |
| 834 » ** Convert shared memory format to local format | 824 ** Convert shared memory format to local format |
| 835 » */ | 825 */ |
| 836 » sid = ConvertToSID(&sce, pcce ? &cce : 0, psnce ? &snce : 0, dbHandle); | 826 sid = ConvertToSID(&sce, pcce ? &cce : 0, psnce ? &snce : 0, dbHandle); |
| 837 } | 827 } |
| 838 return sid; | 828 return sid; |
| 839 } | 829 } |
| 840 | 830 |
| 841 /* | 831 /* |
| 842 ** Place a sid into the cache, if it isn't already there. | 832 ** Place a sid into the cache, if it isn't already there. |
| 843 */ | 833 */ |
| 844 static void | 834 static void |
| 845 ServerSessionIDCache(sslSessionID *sid) | 835 ServerSessionIDCache(sslSessionID *sid) |
| 846 { | 836 { |
| 847 sidCacheEntry sce; | 837 sidCacheEntry sce; |
| 848 PRUint32 now = 0; | 838 PRUint32 now = 0; |
| 849 PRUint16 version = sid->version; | 839 PRUint16 version = sid->version; |
| 850 cacheDesc * cache = &globalCache; | 840 cacheDesc *cache = &globalCache; |
| 851 | 841 |
| 852 if ((version >= SSL_LIBRARY_VERSION_3_0) && | 842 if ((version >= SSL_LIBRARY_VERSION_3_0) && |
| 853 » (sid->u.ssl3.sessionIDLength == 0)) { | 843 (sid->u.ssl3.sessionIDLength == 0)) { |
| 854 » return; | 844 return; |
| 855 } | 845 } |
| 856 | 846 |
| 857 if (sid->cached == never_cached || sid->cached == invalid_cache) { | 847 if (sid->cached == never_cached || sid->cached == invalid_cache) { |
| 858 » PRUint32 set; | 848 PRUint32 set; |
| 859 | 849 |
| 860 » PORT_Assert(sid->creationTime != 0); | 850 PORT_Assert(sid->creationTime != 0); |
| 861 » if (!sid->creationTime) | 851 if (!sid->creationTime) |
| 862 » sid->lastAccessTime = sid->creationTime = ssl_Time(); | 852 sid->lastAccessTime = sid->creationTime = ssl_Time(); |
| 863 » if (version < SSL_LIBRARY_VERSION_3_0) { | 853 if (version < SSL_LIBRARY_VERSION_3_0) { |
| 864 » /* override caller's expiration time, which uses client timeout | 854 /* override caller's expiration time, which uses client timeout |
| 865 » * duration, not server timeout duration. | 855 * duration, not server timeout duration. |
| 866 » */ | 856 */ |
| 867 » sid->expirationTime = sid->creationTime + cache->ssl2Timeout; | 857 sid->expirationTime = sid->creationTime + cache->ssl2Timeout; |
| 868 » SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x tim
e=%x " | 858 SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x tim
e=%x " |
| 869 » » » "cipher=%d", myPid, sid->cached, | 859 "cipher=%d", |
| 870 » » » sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], | 860 myPid, sid->cached, |
| 871 » » » sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], | 861 sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], |
| 872 » » » sid->creationTime, sid->u.ssl2.cipherType)); | 862 sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], |
| 873 » PRINT_BUF(8, (0, "sessionID:", sid->u.ssl2.sessionID, | 863 sid->creationTime, sid->u.ssl2.cipherType)); |
| 874 » » » SSL2_SESSIONID_BYTES)); | 864 PRINT_BUF(8, (0, "sessionID:", sid->u.ssl2.sessionID, |
| 875 » PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data, | 865 SSL2_SESSIONID_BYTES)); |
| 876 » » » sid->u.ssl2.masterKey.len)); | 866 PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data, |
| 877 » PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data, | 867 sid->u.ssl2.masterKey.len)); |
| 878 » » » sid->u.ssl2.cipherArg.len)); | 868 PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data, |
| 869 sid->u.ssl2.cipherArg.len)); |
| 870 } else { |
| 871 /* override caller's expiration time, which uses client timeout |
| 872 * duration, not server timeout duration. |
| 873 */ |
| 874 sid->expirationTime = sid->creationTime + cache->ssl3Timeout; |
| 875 SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x tim
e=%x " |
| 876 "cipherSuite=%d", |
| 877 myPid, sid->cached, |
| 878 sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], |
| 879 sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], |
| 880 sid->creationTime, sid->u.ssl3.cipherSuite)); |
| 881 PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID, |
| 882 sid->u.ssl3.sessionIDLength)); |
| 883 } |
| 879 | 884 |
| 880 » } else { | 885 ConvertFromSID(&sce, sid); |
| 881 » /* override caller's expiration time, which uses client timeout | |
| 882 » * duration, not server timeout duration. | |
| 883 » */ | |
| 884 » sid->expirationTime = sid->creationTime + cache->ssl3Timeout; | |
| 885 » SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x tim
e=%x " | |
| 886 » » » "cipherSuite=%d", myPid, sid->cached, | |
| 887 » » » sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], | |
| 888 » » » sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], | |
| 889 » » » sid->creationTime, sid->u.ssl3.cipherSuite)); | |
| 890 » PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID, | |
| 891 » » » sid->u.ssl3.sessionIDLength)); | |
| 892 » } | |
| 893 | 886 |
| 894 » ConvertFromSID(&sce, sid); | 887 if (version >= SSL_LIBRARY_VERSION_3_0) { |
| 895 | |
| 896 » if (version >= SSL_LIBRARY_VERSION_3_0) { | |
| 897 SECItem *name = &sid->u.ssl3.srvName; | 888 SECItem *name = &sid->u.ssl3.srvName; |
| 898 if (name->len && name->data) { | 889 if (name->len && name->data) { |
| 899 now = CacheSrvName(cache, name, &sce); | 890 now = CacheSrvName(cache, name, &sce); |
| 900 } | 891 } |
| 901 if (sid->peerCert != NULL) { | 892 if (sid->peerCert != NULL) { |
| 902 now = CacheCert(cache, sid->peerCert, &sce); | 893 now = CacheCert(cache, sid->peerCert, &sce); |
| 903 } | 894 } |
| 904 » } | 895 } |
| 905 | 896 |
| 906 » set = SIDindex(cache, &sce.addr, sce.sessionID, sce.sessionIDLength); | 897 set = SIDindex(cache, &sce.addr, sce.sessionID, sce.sessionIDLength); |
| 907 » now = LockSet(cache, set, now); | 898 now = LockSet(cache, set, now); |
| 908 » if (now) { | 899 if (now) { |
| 909 » PRUint32 next = cache->sidCacheSets[set].next; | 900 PRUint32 next = cache->sidCacheSets[set].next; |
| 910 » PRUint32 ndx = set * SID_CACHE_ENTRIES_PER_SET + next; | 901 PRUint32 ndx = set * SID_CACHE_ENTRIES_PER_SET + next; |
| 911 | 902 |
| 912 » /* Write out new cache entry */ | 903 /* Write out new cache entry */ |
| 913 » cache->sidCacheData[ndx] = sce; | 904 cache->sidCacheData[ndx] = sce; |
| 914 | 905 |
| 915 » cache->sidCacheSets[set].next = | 906 cache->sidCacheSets[set].next = |
| 916 » » » » » (next + 1) % SID_CACHE_ENTRIES_PER_SET; | 907 (next + 1) % SID_CACHE_ENTRIES_PER_SET; |
| 917 | 908 |
| 918 » UnlockSet(cache, set); | 909 UnlockSet(cache, set); |
| 919 » sid->cached = in_server_cache; | 910 sid->cached = in_server_cache; |
| 920 » } | 911 } |
| 921 } | 912 } |
| 922 } | 913 } |
| 923 | 914 |
| 924 /* | 915 /* |
| 925 ** Although this is static, it is called from ssl via global function pointer | 916 ** Although this is static, it is called from ssl via global function pointer |
| 926 **» ssl_sid_uncache. This invalidates the referenced cache entry. | 917 ** ssl_sid_uncache. This invalidates the referenced cache entry. |
| 927 */ | 918 */ |
| 928 static void | 919 static void |
| 929 ServerSessionIDUncache(sslSessionID *sid) | 920 ServerSessionIDUncache(sslSessionID *sid) |
| 930 { | 921 { |
| 931 cacheDesc * cache = &globalCache; | 922 cacheDesc *cache = &globalCache; |
| 932 PRUint8 * sessionID; | 923 PRUint8 *sessionID; |
| 933 unsigned int sessionIDLength; | 924 unsigned int sessionIDLength; |
| 934 PRErrorCode err; | 925 PRErrorCode err; |
| 935 PRUint32 set; | 926 PRUint32 set; |
| 936 PRUint32 now; | 927 PRUint32 now; |
| 937 sidCacheEntry *psce; | 928 sidCacheEntry *psce; |
| 938 | 929 |
| 939 if (sid == NULL) | 930 if (sid == NULL) |
| 940 » return; | 931 return; |
| 941 | 932 |
| 942 /* Uncaching a SID should never change the error code. | 933 /* Uncaching a SID should never change the error code. |
| 943 ** So save it here and restore it before exiting. | 934 ** So save it here and restore it before exiting. |
| 944 */ | 935 */ |
| 945 err = PR_GetError(); | 936 err = PR_GetError(); |
| 946 | 937 |
| 947 if (sid->version < SSL_LIBRARY_VERSION_3_0) { | 938 if (sid->version < SSL_LIBRARY_VERSION_3_0) { |
| 948 » sessionID = sid->u.ssl2.sessionID; | 939 sessionID = sid->u.ssl2.sessionID; |
| 949 » sessionIDLength = SSL2_SESSIONID_BYTES; | 940 sessionIDLength = SSL2_SESSIONID_BYTES; |
| 950 » SSL_TRC(8, ("%d: SSL: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%
x " | 941 SSL_TRC(8, ("%d: SSL: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%
x " |
| 951 » » "cipher=%d", myPid, sid->cached, | 942 "cipher=%d", |
| 952 » » sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], | 943 myPid, sid->cached, |
| 953 » » sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], | 944 sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], |
| 954 » » sid->creationTime, sid->u.ssl2.cipherType)); | 945 sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], |
| 955 » PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength)); | 946 sid->creationTime, sid->u.ssl2.cipherType)); |
| 956 » PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data, | 947 PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength)); |
| 957 » » sid->u.ssl2.masterKey.len)); | 948 PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data, |
| 958 » PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data, | 949 sid->u.ssl2.masterKey.len)); |
| 959 » » sid->u.ssl2.cipherArg.len)); | 950 PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data, |
| 951 sid->u.ssl2.cipherArg.len)); |
| 960 } else { | 952 } else { |
| 961 » sessionID = sid->u.ssl3.sessionID; | 953 sessionID = sid->u.ssl3.sessionID; |
| 962 » sessionIDLength = sid->u.ssl3.sessionIDLength; | 954 sessionIDLength = sid->u.ssl3.sessionIDLength; |
| 963 » SSL_TRC(8, ("%d: SSL3: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=
%x " | 955 SSL_TRC(8, ("%d: SSL3: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=
%x " |
| 964 » » "cipherSuite=%d", myPid, sid->cached, | 956 "cipherSuite=%d", |
| 965 » » sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], | 957 myPid, sid->cached, |
| 966 » » sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], | 958 sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], |
| 967 » » sid->creationTime, sid->u.ssl3.cipherSuite)); | 959 sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], |
| 968 » PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength)); | 960 sid->creationTime, sid->u.ssl3.cipherSuite)); |
| 961 PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength)); |
| 969 } | 962 } |
| 970 set = SIDindex(cache, &sid->addr, sessionID, sessionIDLength); | 963 set = SIDindex(cache, &sid->addr, sessionID, sessionIDLength); |
| 971 now = LockSet(cache, set, 0); | 964 now = LockSet(cache, set, 0); |
| 972 if (now) { | 965 if (now) { |
| 973 » psce = FindSID(cache, set, now, &sid->addr, sessionID, sessionIDLength); | 966 psce = FindSID(cache, set, now, &sid->addr, sessionID, sessionIDLength); |
| 974 » if (psce) { | 967 if (psce) { |
| 975 » psce->valid = 0; | 968 psce->valid = 0; |
| 976 » } | 969 } |
| 977 » UnlockSet(cache, set); | 970 UnlockSet(cache, set); |
| 978 } | 971 } |
| 979 sid->cached = invalid_cache; | 972 sid->cached = invalid_cache; |
| 980 PORT_SetError(err); | 973 PORT_SetError(err); |
| 981 } | 974 } |
| 982 | 975 |
| 983 #ifdef XP_OS2 | 976 #ifdef XP_OS2 |
| 984 | 977 |
| 985 #define INCL_DOSPROCESS | 978 #define INCL_DOSPROCESS |
| 986 #include <os2.h> | 979 #include <os2.h> |
| 987 | 980 |
| 988 long gettid(void) | 981 long |
| 982 gettid(void) |
| 989 { | 983 { |
| 990 PTIB ptib; | 984 PTIB ptib; |
| 991 PPIB ppib; | 985 PPIB ppib; |
| 992 DosGetInfoBlocks(&ptib, &ppib); | 986 DosGetInfoBlocks(&ptib, &ppib); |
| 993 return ((long)ptib->tib_ordinal); /* thread id */ | 987 return ((long)ptib->tib_ordinal); /* thread id */ |
| 994 } | 988 } |
| 995 #endif | 989 #endif |
| 996 | 990 |
| 997 static void | 991 static void |
| 998 CloseCache(cacheDesc *cache) | 992 CloseCache(cacheDesc *cache) |
| 999 { | 993 { |
| 1000 int locks_initialized = cache->numSIDCacheLocksInitialized; | 994 int locks_initialized = cache->numSIDCacheLocksInitialized; |
| 1001 | 995 |
| 1002 if (cache->cacheMem) { | 996 if (cache->cacheMem) { |
| 1003 » if (cache->sharedCache) { | 997 if (cache->sharedCache) { |
| 1004 » sidCacheLock *pLock = cache->sidCacheLocks; | 998 sidCacheLock *pLock = cache->sidCacheLocks; |
| 1005 » for (; locks_initialized > 0; --locks_initialized, ++pLock ) { | 999 for (; locks_initialized > 0; --locks_initialized, ++pLock) { |
| 1006 » » /* If everInherited is true, this shared cache was (and may | 1000 /* If everInherited is true, this shared cache was (and may |
| 1007 » » ** still be) in use by multiple processes. We do not wish to | 1001 ** still be) in use by multiple processes. We do not wish to |
| 1008 » » ** destroy the mutexes while they are still in use, but we do | 1002 ** destroy the mutexes while they are still in use, but we do |
| 1009 » » ** want to free mutex resources associated with this process. | 1003 ** want to free mutex resources associated with this process. |
| 1010 » » */ | 1004 */ |
| 1011 » » sslMutex_Destroy(&pLock->mutex, | 1005 sslMutex_Destroy(&pLock->mutex, |
| 1012 » » » » cache->sharedCache->everInherited); | 1006 cache->sharedCache->everInherited); |
| 1013 » } | 1007 } |
| 1014 » } | 1008 } |
| 1015 » if (cache->shared) { | 1009 if (cache->shared) { |
| 1016 » PR_MemUnmap(cache->cacheMem, cache->cacheMemSize); | 1010 PR_MemUnmap(cache->cacheMem, cache->cacheMemSize); |
| 1017 » } else { | 1011 } else { |
| 1018 » PORT_Free(cache->cacheMem); | 1012 PORT_Free(cache->cacheMem); |
| 1019 » } | 1013 } |
| 1020 » cache->cacheMem = NULL; | 1014 cache->cacheMem = NULL; |
| 1021 } | 1015 } |
| 1022 if (cache->cacheMemMap) { | 1016 if (cache->cacheMemMap) { |
| 1023 » PR_CloseFileMap(cache->cacheMemMap); | 1017 PR_CloseFileMap(cache->cacheMemMap); |
| 1024 » cache->cacheMemMap = NULL; | 1018 cache->cacheMemMap = NULL; |
| 1025 } | 1019 } |
| 1026 memset(cache, 0, sizeof *cache); | 1020 memset(cache, 0, sizeof *cache); |
| 1027 } | 1021 } |
| 1028 | 1022 |
| 1029 static SECStatus | 1023 static SECStatus |
| 1030 InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries, | 1024 InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries, |
| 1031 int maxSrvNameCacheEntries, PRUint32 ssl2_timeout, | 1025 int maxSrvNameCacheEntries, PRUint32 ssl2_timeout, |
| 1032 PRUint32 ssl3_timeout, const char *directory, PRBool shared) | 1026 PRUint32 ssl3_timeout, const char *directory, PRBool shared) |
| 1033 { | 1027 { |
| 1034 ptrdiff_t ptr; | 1028 ptrdiff_t ptr; |
| 1035 sidCacheLock *pLock; | 1029 sidCacheLock *pLock; |
| 1036 char * cacheMem; | 1030 char *cacheMem; |
| 1037 PRFileMap * cacheMemMap; | 1031 PRFileMap *cacheMemMap; |
| 1038 char * cfn = NULL;» /* cache file name */ | 1032 char *cfn = NULL; /* cache file name */ |
| 1039 int locks_initialized = 0; | 1033 int locks_initialized = 0; |
| 1040 int locks_to_initialize = 0; | 1034 int locks_to_initialize = 0; |
| 1041 PRUint32 init_time; | 1035 PRUint32 init_time; |
| 1042 | 1036 |
| 1043 if ( (!cache) || (maxCacheEntries < 0) || (!directory) ) { | 1037 if ((!cache) || (maxCacheEntries < 0) || (!directory)) { |
| 1044 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1038 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1045 return SECFailure; | 1039 return SECFailure; |
| 1046 } | 1040 } |
| 1047 | 1041 |
| 1048 if (cache->cacheMem) { | 1042 if (cache->cacheMem) { |
| 1049 » /* Already done */ | 1043 /* Already done */ |
| 1050 » return SECSuccess; | 1044 return SECSuccess; |
| 1051 } | 1045 } |
| 1052 | 1046 |
| 1053 /* make sure loser can clean up properly */ | 1047 /* make sure loser can clean up properly */ |
| 1054 cache->shared = shared; | 1048 cache->shared = shared; |
| 1055 cache->cacheMem = cacheMem = NULL; | 1049 cache->cacheMem = cacheMem = NULL; |
| 1056 cache->cacheMemMap = cacheMemMap = NULL; | 1050 cache->cacheMemMap = cacheMemMap = NULL; |
| 1057 cache->sharedCache = (cacheDesc *)0; | 1051 cache->sharedCache = (cacheDesc *)0; |
| 1058 | 1052 |
| 1059 cache->numSIDCacheLocksInitialized = 0; | 1053 cache->numSIDCacheLocksInitialized = 0; |
| 1060 cache->nextCertCacheEntry = 0; | 1054 cache->nextCertCacheEntry = 0; |
| 1061 cache->stopPolling = PR_FALSE; | 1055 cache->stopPolling = PR_FALSE; |
| 1062 cache->everInherited = PR_FALSE; | 1056 cache->everInherited = PR_FALSE; |
| 1063 cache->poller = NULL; | 1057 cache->poller = NULL; |
| 1064 cache->mutexTimeout = 0; | 1058 cache->mutexTimeout = 0; |
| 1065 | 1059 |
| 1066 cache->numSIDCacheEntries = maxCacheEntries ? maxCacheEntries | 1060 cache->numSIDCacheEntries = maxCacheEntries ? maxCacheEntries |
| 1067 : DEF_SID_CACHE_ENTRIES; | 1061 : DEF_SID_CACHE_ENTRIES; |
| 1068 cache->numSIDCacheSets = | 1062 cache->numSIDCacheSets = |
| 1069 » SID_HOWMANY(cache->numSIDCacheEntries, SID_CACHE_ENTRIES_PER_SET); | 1063 SID_HOWMANY(cache->numSIDCacheEntries, SID_CACHE_ENTRIES_PER_SET); |
| 1070 | 1064 |
| 1071 cache->numSIDCacheEntries = | 1065 cache->numSIDCacheEntries = |
| 1072 » cache->numSIDCacheSets * SID_CACHE_ENTRIES_PER_SET; | 1066 cache->numSIDCacheSets * SID_CACHE_ENTRIES_PER_SET; |
| 1073 | 1067 |
| 1074 cache->numSIDCacheLocks = | 1068 cache->numSIDCacheLocks = |
| 1075 » PR_MIN(cache->numSIDCacheSets, ssl_max_sid_cache_locks); | 1069 PR_MIN(cache->numSIDCacheSets, ssl_max_sid_cache_locks); |
| 1076 | 1070 |
| 1077 cache->numSIDCacheSetsPerLock = | 1071 cache->numSIDCacheSetsPerLock = |
| 1078 » SID_HOWMANY(cache->numSIDCacheSets, cache->numSIDCacheLocks); | 1072 SID_HOWMANY(cache->numSIDCacheSets, cache->numSIDCacheLocks); |
| 1079 | 1073 |
| 1080 cache->numCertCacheEntries = (maxCertCacheEntries > 0) ? | 1074 cache->numCertCacheEntries = (maxCertCacheEntries > 0) ? maxCertCacheEntries |
| 1081 maxCertCacheEntries : 0; | 1075 : 0; |
| 1082 cache->numSrvNameCacheEntries = (maxSrvNameCacheEntries >= 0) ? | 1076 cache->numSrvNameCacheEntries = (maxSrvNameCacheEntries >= 0) ? maxSrvNameCa
cheEntries |
| 1083 maxSrvNameCacheEntries : DEF_NAME_C
ACHE_ENTRIES; | 1077 : DEF_NAME_CAC
HE_ENTRIES; |
| 1084 | 1078 |
| 1085 /* compute size of shared memory, and offsets of all pointers */ | 1079 /* compute size of shared memory, and offsets of all pointers */ |
| 1086 ptr = 0; | 1080 ptr = 0; |
| 1087 cache->cacheMem = (char *)ptr; | 1081 cache->cacheMem = (char *)ptr; |
| 1088 ptr += SID_ROUNDUP(sizeof(cacheDesc), SID_ALIGNMENT); | 1082 ptr += SID_ROUNDUP(sizeof(cacheDesc), SID_ALIGNMENT); |
| 1089 | 1083 |
| 1090 cache->sidCacheLocks = (sidCacheLock *)ptr; | 1084 cache->sidCacheLocks = (sidCacheLock *)ptr; |
| 1091 cache->keyCacheLock = cache->sidCacheLocks + cache->numSIDCacheLocks; | 1085 cache->keyCacheLock = cache->sidCacheLocks + cache->numSIDCacheLocks; |
| 1092 cache->certCacheLock = cache->keyCacheLock + 1; | 1086 cache->certCacheLock = cache->keyCacheLock + 1; |
| 1093 cache->srvNameCacheLock = cache->certCacheLock + 1; | 1087 cache->srvNameCacheLock = cache->certCacheLock + 1; |
| 1094 ptr = (ptrdiff_t)(cache->srvNameCacheLock + 1); | 1088 ptr = (ptrdiff_t)(cache->srvNameCacheLock + 1); |
| 1095 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); | 1089 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); |
| 1096 | 1090 |
| 1097 cache->sidCacheSets = (sidCacheSet *)ptr; | 1091 cache->sidCacheSets = (sidCacheSet *)ptr; |
| 1098 ptr = (ptrdiff_t)(cache->sidCacheSets + cache->numSIDCacheSets); | 1092 ptr = (ptrdiff_t)(cache->sidCacheSets + cache->numSIDCacheSets); |
| 1099 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); | 1093 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); |
| 1100 | 1094 |
| 1101 cache->sidCacheData = (sidCacheEntry *)ptr; | 1095 cache->sidCacheData = (sidCacheEntry *)ptr; |
| 1102 ptr = (ptrdiff_t)(cache->sidCacheData + cache->numSIDCacheEntries); | 1096 ptr = (ptrdiff_t)(cache->sidCacheData + cache->numSIDCacheEntries); |
| 1103 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); | 1097 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); |
| 1104 | 1098 |
| 1105 cache->certCacheData = (certCacheEntry *)ptr; | 1099 cache->certCacheData = (certCacheEntry *)ptr; |
| 1106 cache->sidCacheSize = | 1100 cache->sidCacheSize = |
| 1107 » (char *)cache->certCacheData - (char *)cache->sidCacheData; | 1101 (char *)cache->certCacheData - (char *)cache->sidCacheData; |
| 1108 | 1102 |
| 1109 if (cache->numCertCacheEntries < MIN_CERT_CACHE_ENTRIES) { | 1103 if (cache->numCertCacheEntries < MIN_CERT_CACHE_ENTRIES) { |
| 1110 /* This is really a poor way to computer this! */ | 1104 /* This is really a poor way to computer this! */ |
| 1111 cache->numCertCacheEntries = cache->sidCacheSize / sizeof(certCacheEntry
); | 1105 cache->numCertCacheEntries = cache->sidCacheSize / sizeof(certCacheEntry
); |
| 1112 if (cache->numCertCacheEntries < MIN_CERT_CACHE_ENTRIES) | 1106 if (cache->numCertCacheEntries < MIN_CERT_CACHE_ENTRIES) |
| 1113 » cache->numCertCacheEntries = MIN_CERT_CACHE_ENTRIES; | 1107 cache->numCertCacheEntries = MIN_CERT_CACHE_ENTRIES; |
| 1114 } | 1108 } |
| 1115 ptr = (ptrdiff_t)(cache->certCacheData + cache->numCertCacheEntries); | 1109 ptr = (ptrdiff_t)(cache->certCacheData + cache->numCertCacheEntries); |
| 1116 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); | 1110 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); |
| 1117 | 1111 |
| 1118 cache->keyCacheData = (SSLWrappedSymWrappingKey *)ptr; | 1112 cache->keyCacheData = (SSLWrappedSymWrappingKey *)ptr; |
| 1119 cache->certCacheSize = | 1113 cache->certCacheSize = |
| 1120 » (char *)cache->keyCacheData - (char *)cache->certCacheData; | 1114 (char *)cache->keyCacheData - (char *)cache->certCacheData; |
| 1121 | 1115 |
| 1122 cache->numKeyCacheEntries = kt_kea_size * SSL_NUM_WRAP_MECHS; | 1116 cache->numKeyCacheEntries = kt_kea_size * SSL_NUM_WRAP_MECHS; |
| 1123 ptr = (ptrdiff_t)(cache->keyCacheData + cache->numKeyCacheEntries); | 1117 ptr = (ptrdiff_t)(cache->keyCacheData + cache->numKeyCacheEntries); |
| 1124 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); | 1118 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); |
| 1125 | 1119 |
| 1126 cache->keyCacheSize = (char *)ptr - (char *)cache->keyCacheData; | 1120 cache->keyCacheSize = (char *)ptr - (char *)cache->keyCacheData; |
| 1127 | 1121 |
| 1128 cache->ticketKeyNameSuffix = (PRUint8 *)ptr; | 1122 cache->ticketKeyNameSuffix = (PRUint8 *)ptr; |
| 1129 ptr = (ptrdiff_t)(cache->ticketKeyNameSuffix + | 1123 ptr = (ptrdiff_t)(cache->ticketKeyNameSuffix + |
| 1130 » SESS_TICKET_KEY_VAR_NAME_LEN); | 1124 SESS_TICKET_KEY_VAR_NAME_LEN); |
| 1131 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); | 1125 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); |
| 1132 | 1126 |
| 1133 cache->ticketEncKey = (encKeyCacheEntry *)ptr; | 1127 cache->ticketEncKey = (encKeyCacheEntry *)ptr; |
| 1134 ptr = (ptrdiff_t)(cache->ticketEncKey + 1); | 1128 ptr = (ptrdiff_t)(cache->ticketEncKey + 1); |
| 1135 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); | 1129 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); |
| 1136 | 1130 |
| 1137 cache->ticketMacKey = (encKeyCacheEntry *)ptr; | 1131 cache->ticketMacKey = (encKeyCacheEntry *)ptr; |
| 1138 ptr = (ptrdiff_t)(cache->ticketMacKey + 1); | 1132 ptr = (ptrdiff_t)(cache->ticketMacKey + 1); |
| 1139 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); | 1133 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); |
| 1140 | 1134 |
| 1141 cache->ticketKeysValid = (PRUint32 *)ptr; | 1135 cache->ticketKeysValid = (PRUint32 *)ptr; |
| 1142 ptr = (ptrdiff_t)(cache->ticketKeysValid + 1); | 1136 ptr = (ptrdiff_t)(cache->ticketKeysValid + 1); |
| 1143 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); | 1137 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); |
| 1144 | 1138 |
| 1145 cache->srvNameCacheData = (srvNameCacheEntry *)ptr; | 1139 cache->srvNameCacheData = (srvNameCacheEntry *)ptr; |
| 1146 cache->srvNameCacheSize = | 1140 cache->srvNameCacheSize = |
| 1147 cache->numSrvNameCacheEntries * sizeof(srvNameCacheEntry); | 1141 cache->numSrvNameCacheEntries * sizeof(srvNameCacheEntry); |
| 1148 ptr = (ptrdiff_t)(cache->srvNameCacheData + cache->numSrvNameCacheEntries); | 1142 ptr = (ptrdiff_t)(cache->srvNameCacheData + cache->numSrvNameCacheEntries); |
| 1149 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); | 1143 ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); |
| 1150 | 1144 |
| 1151 cache->cacheMemSize = ptr; | 1145 cache->cacheMemSize = ptr; |
| 1152 | 1146 |
| 1153 if (ssl2_timeout) { | 1147 if (ssl2_timeout) { |
| 1154 » if (ssl2_timeout > MAX_SSL2_TIMEOUT) { | 1148 if (ssl2_timeout > MAX_SSL2_TIMEOUT) { |
| 1155 » ssl2_timeout = MAX_SSL2_TIMEOUT; | 1149 ssl2_timeout = MAX_SSL2_TIMEOUT; |
| 1156 » } | 1150 } |
| 1157 » if (ssl2_timeout < MIN_SSL2_TIMEOUT) { | 1151 if (ssl2_timeout < MIN_SSL2_TIMEOUT) { |
| 1158 » ssl2_timeout = MIN_SSL2_TIMEOUT; | 1152 ssl2_timeout = MIN_SSL2_TIMEOUT; |
| 1159 » } | 1153 } |
| 1160 » cache->ssl2Timeout = ssl2_timeout; | 1154 cache->ssl2Timeout = ssl2_timeout; |
| 1161 } else { | 1155 } else { |
| 1162 » cache->ssl2Timeout = DEF_SSL2_TIMEOUT; | 1156 cache->ssl2Timeout = DEF_SSL2_TIMEOUT; |
| 1163 } | 1157 } |
| 1164 | 1158 |
| 1165 if (ssl3_timeout) { | 1159 if (ssl3_timeout) { |
| 1166 » if (ssl3_timeout > MAX_SSL3_TIMEOUT) { | 1160 if (ssl3_timeout > MAX_SSL3_TIMEOUT) { |
| 1167 » ssl3_timeout = MAX_SSL3_TIMEOUT; | 1161 ssl3_timeout = MAX_SSL3_TIMEOUT; |
| 1168 » } | 1162 } |
| 1169 » if (ssl3_timeout < MIN_SSL3_TIMEOUT) { | 1163 if (ssl3_timeout < MIN_SSL3_TIMEOUT) { |
| 1170 » ssl3_timeout = MIN_SSL3_TIMEOUT; | 1164 ssl3_timeout = MIN_SSL3_TIMEOUT; |
| 1171 » } | 1165 } |
| 1172 » cache->ssl3Timeout = ssl3_timeout; | 1166 cache->ssl3Timeout = ssl3_timeout; |
| 1173 } else { | 1167 } else { |
| 1174 » cache->ssl3Timeout = DEF_SSL3_TIMEOUT; | 1168 cache->ssl3Timeout = DEF_SSL3_TIMEOUT; |
| 1175 } | 1169 } |
| 1176 | 1170 |
| 1177 if (shared) { | 1171 if (shared) { |
| 1178 » /* Create file names */ | 1172 /* Create file names */ |
| 1179 #if defined(XP_UNIX) || defined(XP_BEOS) | 1173 #if defined(XP_UNIX) || defined(XP_BEOS) |
| 1180 » /* there's some confusion here about whether PR_OpenAnonFileMap wants | 1174 /* there's some confusion here about whether PR_OpenAnonFileMap wants |
| 1181 » ** a directory name or a file name for its first argument. | 1175 ** a directory name or a file name for its first argument. |
| 1182 » cfn = PR_smprintf("%s/.sslsvrcache.%d", directory, myPid); | 1176 cfn = PR_smprintf("%s/.sslsvrcache.%d", directory, myPid); |
| 1183 » */ | 1177 */ |
| 1184 » cfn = PR_smprintf("%s", directory); | 1178 cfn = PR_smprintf("%s", directory); |
| 1185 #elif defined(XP_WIN32) | 1179 #elif defined(XP_WIN32) |
| 1186 » cfn = PR_smprintf("%s/svrcache_%d_%x.ssl", directory, myPid, | 1180 cfn = PR_smprintf("%s/svrcache_%d_%x.ssl", directory, myPid, |
| 1187 » » » GetCurrentThreadId()); | 1181 GetCurrentThreadId()); |
| 1188 #elif defined(XP_OS2) | 1182 #elif defined(XP_OS2) |
| 1189 » cfn = PR_smprintf("%s/svrcache_%d_%x.ssl", directory, myPid, | 1183 cfn = PR_smprintf("%s/svrcache_%d_%x.ssl", directory, myPid, |
| 1190 » » » gettid()); | 1184 gettid()); |
| 1191 #else | 1185 #else |
| 1192 #error "Don't know how to create file name for this platform!" | 1186 #error "Don't know how to create file name for this platform!" |
| 1193 #endif | 1187 #endif |
| 1194 » if (!cfn) { | 1188 if (!cfn) { |
| 1195 » goto loser; | 1189 goto loser; |
| 1196 » } | 1190 } |
| 1197 | 1191 |
| 1198 » /* Create cache */ | 1192 /* Create cache */ |
| 1199 » cacheMemMap = PR_OpenAnonFileMap(cfn, cache->cacheMemSize, | 1193 cacheMemMap = PR_OpenAnonFileMap(cfn, cache->cacheMemSize, |
| 1200 » » » » » PR_PROT_READWRITE); | 1194 PR_PROT_READWRITE); |
| 1201 | 1195 |
| 1202 » PR_smprintf_free(cfn); | 1196 PR_smprintf_free(cfn); |
| 1203 » if(!cacheMemMap) { | 1197 if (!cacheMemMap) { |
| 1204 » goto loser; | 1198 goto loser; |
| 1205 » } | 1199 } |
| 1206 | 1200 |
| 1207 cacheMem = PR_MemMap(cacheMemMap, 0, cache->cacheMemSize); | 1201 cacheMem = PR_MemMap(cacheMemMap, 0, cache->cacheMemSize); |
| 1208 } else { | 1202 } else { |
| 1209 cacheMem = PORT_Alloc(cache->cacheMemSize); | 1203 cacheMem = PORT_Alloc(cache->cacheMemSize); |
| 1210 } | 1204 } |
| 1211 | 1205 |
| 1212 if (! cacheMem) { | 1206 if (!cacheMem) { |
| 1213 goto loser; | 1207 goto loser; |
| 1214 } | 1208 } |
| 1215 | 1209 |
| 1216 /* Initialize shared memory. This may not be necessary on all platforms */ | 1210 /* Initialize shared memory. This may not be necessary on all platforms */ |
| 1217 memset(cacheMem, 0, cache->cacheMemSize); | 1211 memset(cacheMem, 0, cache->cacheMemSize); |
| 1218 | 1212 |
| 1219 /* Copy cache descriptor header into shared memory */ | 1213 /* Copy cache descriptor header into shared memory */ |
| 1220 memcpy(cacheMem, cache, sizeof *cache); | 1214 memcpy(cacheMem, cache, sizeof *cache); |
| 1221 | 1215 |
| 1222 /* save private copies of these values */ | 1216 /* save private copies of these values */ |
| 1223 cache->cacheMemMap = cacheMemMap; | 1217 cache->cacheMemMap = cacheMemMap; |
| 1224 cache->cacheMem = cacheMem; | 1218 cache->cacheMem = cacheMem; |
| 1225 cache->sharedCache = (cacheDesc *)cacheMem; | 1219 cache->sharedCache = (cacheDesc *)cacheMem; |
| 1226 | 1220 |
| 1227 /* Fix pointers in our private copy of cache descriptor to point to | 1221 /* Fix pointers in our private copy of cache descriptor to point to |
| 1228 ** spaces in shared memory | 1222 ** spaces in shared memory |
| 1229 */ | 1223 */ |
| 1230 cache->sidCacheLocks = (sidCacheLock *) | 1224 cache->sidCacheLocks = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->
sidCacheLocks); |
| 1231 (cache->cacheMem + (ptrdiff_t)cache->sidCacheLocks); | 1225 cache->keyCacheLock = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->k
eyCacheLock); |
| 1232 cache->keyCacheLock = (sidCacheLock *) | 1226 cache->certCacheLock = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->
certCacheLock); |
| 1233 (cache->cacheMem + (ptrdiff_t)cache->keyCacheLock); | 1227 cache->srvNameCacheLock = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cach
e->srvNameCacheLock); |
| 1234 cache->certCacheLock = (sidCacheLock *) | 1228 cache->sidCacheSets = (sidCacheSet *)(cache->cacheMem + (ptrdiff_t)cache->si
dCacheSets); |
| 1235 (cache->cacheMem + (ptrdiff_t)cache->certCacheLock); | 1229 cache->sidCacheData = (sidCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->
sidCacheData); |
| 1236 cache->srvNameCacheLock = (sidCacheLock *) | 1230 cache->certCacheData = (certCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache
->certCacheData); |
| 1237 (cache->cacheMem + (ptrdiff_t)cache->srvNameCacheLock); | 1231 cache->keyCacheData = (SSLWrappedSymWrappingKey *)(cache->cacheMem + (ptrdif
f_t)cache->keyCacheData); |
| 1238 cache->sidCacheSets = (sidCacheSet *) | 1232 cache->ticketKeyNameSuffix = (PRUint8 *)(cache->cacheMem + (ptrdiff_t)cache-
>ticketKeyNameSuffix); |
| 1239 (cache->cacheMem + (ptrdiff_t)cache->sidCacheSets); | 1233 cache->ticketEncKey = (encKeyCacheEntry *)(cache->cacheMem + (ptrdiff_t)cach
e->ticketEncKey); |
| 1240 cache->sidCacheData = (sidCacheEntry *) | 1234 cache->ticketMacKey = (encKeyCacheEntry *)(cache->cacheMem + (ptrdiff_t)cach
e->ticketMacKey); |
| 1241 (cache->cacheMem + (ptrdiff_t)cache->sidCacheData); | 1235 cache->ticketKeysValid = (PRUint32 *)(cache->cacheMem + (ptrdiff_t)cache->ti
cketKeysValid); |
| 1242 cache->certCacheData = (certCacheEntry *) | 1236 cache->srvNameCacheData = (srvNameCacheEntry *)(cache->cacheMem + (ptrdiff_t
)cache->srvNameCacheData); |
| 1243 (cache->cacheMem + (ptrdiff_t)cache->certCacheData); | |
| 1244 cache->keyCacheData = (SSLWrappedSymWrappingKey *) | |
| 1245 (cache->cacheMem + (ptrdiff_t)cache->keyCacheData); | |
| 1246 cache->ticketKeyNameSuffix = (PRUint8 *) | |
| 1247 (cache->cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix); | |
| 1248 cache->ticketEncKey = (encKeyCacheEntry *) | |
| 1249 (cache->cacheMem + (ptrdiff_t)cache->ticketEncKey); | |
| 1250 cache->ticketMacKey = (encKeyCacheEntry *) | |
| 1251 (cache->cacheMem + (ptrdiff_t)cache->ticketMacKey); | |
| 1252 cache->ticketKeysValid = (PRUint32 *) | |
| 1253 (cache->cacheMem + (ptrdiff_t)cache->ticketKeysValid); | |
| 1254 cache->srvNameCacheData = (srvNameCacheEntry *) | |
| 1255 (cache->cacheMem + (ptrdiff_t)cache->srvNameCacheData); | |
| 1256 | 1237 |
| 1257 /* initialize the locks */ | 1238 /* initialize the locks */ |
| 1258 init_time = ssl_Time(); | 1239 init_time = ssl_Time(); |
| 1259 pLock = cache->sidCacheLocks; | 1240 pLock = cache->sidCacheLocks; |
| 1260 for (locks_to_initialize = cache->numSIDCacheLocks + 3; | 1241 for (locks_to_initialize = cache->numSIDCacheLocks + 3; |
| 1261 locks_initialized < locks_to_initialize; | 1242 locks_initialized < locks_to_initialize; |
| 1262 » ++locks_initialized, ++pLock ) { | 1243 ++locks_initialized, ++pLock) { |
| 1263 | 1244 |
| 1264 » SECStatus err = sslMutex_Init(&pLock->mutex, shared); | 1245 SECStatus err = sslMutex_Init(&pLock->mutex, shared); |
| 1265 » if (err) { | 1246 if (err) { |
| 1266 » cache->numSIDCacheLocksInitialized = locks_initialized; | 1247 cache->numSIDCacheLocksInitialized = locks_initialized; |
| 1267 » goto loser; | 1248 goto loser; |
| 1268 » } | 1249 } |
| 1269 pLock->timeStamp = init_time; | 1250 pLock->timeStamp = init_time; |
| 1270 » pLock->pid = 0; | 1251 pLock->pid = 0; |
| 1271 } | 1252 } |
| 1272 cache->numSIDCacheLocksInitialized = locks_initialized; | 1253 cache->numSIDCacheLocksInitialized = locks_initialized; |
| 1273 | 1254 |
| 1274 return SECSuccess; | 1255 return SECSuccess; |
| 1275 | 1256 |
| 1276 loser: | 1257 loser: |
| 1277 CloseCache(cache); | 1258 CloseCache(cache); |
| 1278 return SECFailure; | 1259 return SECFailure; |
| 1279 } | 1260 } |
| 1280 | 1261 |
| 1281 PRUint32 | 1262 PRUint32 |
| 1282 SSL_GetMaxServerCacheLocks(void) | 1263 SSL_GetMaxServerCacheLocks(void) |
| 1283 { | 1264 { |
| 1284 return ssl_max_sid_cache_locks + 2; | 1265 return ssl_max_sid_cache_locks + 2; |
| 1285 /* The extra two are the cert cache lock and the key cache lock. */ | 1266 /* The extra two are the cert cache lock and the key cache lock. */ |
| 1286 } | 1267 } |
| 1287 | 1268 |
| 1288 SECStatus | 1269 SECStatus |
| 1289 SSL_SetMaxServerCacheLocks(PRUint32 maxLocks) | 1270 SSL_SetMaxServerCacheLocks(PRUint32 maxLocks) |
| 1290 { | 1271 { |
| 1291 /* Minimum is 1 sid cache lock, 1 cert cache lock and 1 key cache lock. | 1272 /* Minimum is 1 sid cache lock, 1 cert cache lock and 1 key cache lock. |
| 1292 ** We'd like to test for a maximum value, but not all platforms' header | 1273 ** We'd like to test for a maximum value, but not all platforms' header |
| 1293 ** files provide a symbol or function or other means of determining | 1274 ** files provide a symbol or function or other means of determining |
| 1294 ** the maximum, other than trial and error. | 1275 ** the maximum, other than trial and error. |
| 1295 */ | 1276 */ |
| 1296 if (maxLocks < 3) { | 1277 if (maxLocks < 3) { |
| 1297 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1278 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1298 » return SECFailure; | 1279 return SECFailure; |
| 1299 } | 1280 } |
| 1300 ssl_max_sid_cache_locks = maxLocks - 2; | 1281 ssl_max_sid_cache_locks = maxLocks - 2; |
| 1301 /* The extra two are the cert cache lock and the key cache lock. */ | 1282 /* The extra two are the cert cache lock and the key cache lock. */ |
| 1302 return SECSuccess; | 1283 return SECSuccess; |
| 1303 } | 1284 } |
| 1304 | 1285 |
| 1305 static SECStatus | 1286 static SECStatus |
| 1306 ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache, | 1287 ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache, |
| 1307 PRUint32 ssl2_timeout, | 1288 PRUint32 ssl2_timeout, |
| 1308 PRUint32 ssl3_timeout, | 1289 PRUint32 ssl3_timeout, |
| 1309 const char * directory, | 1290 const char *directory, |
| 1310 PRBool shared, | 1291 PRBool shared, |
| 1311 int maxCacheEntries, | 1292 int maxCacheEntries, |
| 1312 int maxCertCacheEntries, | 1293 int maxCertCacheEntries, |
| 1313 int maxSrvNameCacheEntries) | 1294 int maxSrvNameCacheEntries) |
| 1314 { | 1295 { |
| 1315 SECStatus rv; | 1296 SECStatus rv; |
| 1316 | 1297 |
| 1317 PORT_Assert(sizeof(sidCacheEntry) == 192); | 1298 PORT_Assert(sizeof(sidCacheEntry) == 192); |
| 1318 PORT_Assert(sizeof(certCacheEntry) == 4096); | 1299 PORT_Assert(sizeof(certCacheEntry) == 4096); |
| 1319 PORT_Assert(sizeof(srvNameCacheEntry) == 1072); | 1300 PORT_Assert(sizeof(srvNameCacheEntry) == 1072); |
| 1320 | 1301 |
| 1321 rv = ssl_Init(); | 1302 rv = ssl_Init(); |
| 1322 if (rv != SECSuccess) { | 1303 if (rv != SECSuccess) { |
| 1323 » return rv; | 1304 return rv; |
| 1324 } | 1305 } |
| 1325 | 1306 |
| 1326 myPid = SSL_GETPID(); | 1307 myPid = SSL_GETPID(); |
| 1327 if (!directory) { | 1308 if (!directory) { |
| 1328 » directory = DEFAULT_CACHE_DIRECTORY; | 1309 directory = DEFAULT_CACHE_DIRECTORY; |
| 1329 } | 1310 } |
| 1330 rv = InitCache(cache, maxCacheEntries, maxCertCacheEntries, | 1311 rv = InitCache(cache, maxCacheEntries, maxCertCacheEntries, |
| 1331 maxSrvNameCacheEntries, ssl2_timeout, ssl3_timeout, | 1312 maxSrvNameCacheEntries, ssl2_timeout, ssl3_timeout, |
| 1332 directory, shared); | 1313 directory, shared); |
| 1333 if (rv) { | 1314 if (rv) { |
| 1334 » SET_ERROR_CODE | 1315 SET_ERROR_CODE |
| 1335 » return SECFailure; | 1316 return SECFailure; |
| 1336 } | 1317 } |
| 1337 | 1318 |
| 1338 ssl_sid_lookup = ServerSessionIDLookup; | 1319 ssl_sid_lookup = ServerSessionIDLookup; |
| 1339 ssl_sid_cache = ServerSessionIDCache; | 1320 ssl_sid_cache = ServerSessionIDCache; |
| 1340 ssl_sid_uncache = ServerSessionIDUncache; | 1321 ssl_sid_uncache = ServerSessionIDUncache; |
| 1341 return SECSuccess; | 1322 return SECSuccess; |
| 1342 } | 1323 } |
| 1343 | 1324 |
| 1344 SECStatus | 1325 SECStatus |
| 1345 SSL_ConfigServerSessionIDCacheInstance(»cacheDesc *cache, | 1326 SSL_ConfigServerSessionIDCacheInstance(cacheDesc *cache, |
| 1346 int maxCacheEntries, | 1327 int maxCacheEntries, |
| 1347 PRUint32 ssl2_timeout, | 1328 PRUint32 ssl2_timeout, |
| 1348 PRUint32 ssl3_timeout, | 1329 PRUint32 ssl3_timeout, |
| 1349 const char * directory, PRBool shared) | 1330 const char *directory, PRBool shared) |
| 1350 { | 1331 { |
| 1351 return ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache, | 1332 return ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache, |
| 1352 ssl2_timeout, | 1333 ssl2_timeout, |
| 1353 ssl3_timeout, | 1334 ssl3_timeout, |
| 1354 directory, | 1335 directory, |
| 1355 shared, | 1336 shared, |
| 1356 maxCacheEntries, | 1337 maxCacheEntries, |
| 1357 -1, -1); | 1338 -1, -1); |
| 1358 } | 1339 } |
| 1359 | 1340 |
| 1360 SECStatus | 1341 SECStatus |
| 1361 SSL_ConfigServerSessionIDCache(»int maxCacheEntries, | 1342 SSL_ConfigServerSessionIDCache(int maxCacheEntries, |
| 1362 » » » » PRUint32 ssl2_timeout, | 1343 PRUint32 ssl2_timeout, |
| 1363 » » » »PRUint32 ssl3_timeout, | 1344 PRUint32 ssl3_timeout, |
| 1364 » » » const char * directory) | 1345 const char *directory) |
| 1365 { | 1346 { |
| 1366 ssl_InitSessionCacheLocks(); | 1347 ssl_InitSessionCacheLocks(); |
| 1367 return SSL_ConfigServerSessionIDCacheInstance(&globalCache, | 1348 return SSL_ConfigServerSessionIDCacheInstance(&globalCache, |
| 1368 » » maxCacheEntries, ssl2_timeout, ssl3_timeout, directory, PR_FALSE
); | 1349 maxCacheEntries, ssl2_timeout,
ssl3_timeout, directory, PR_FALSE); |
| 1369 } | 1350 } |
| 1370 | 1351 |
| 1371 SECStatus | 1352 SECStatus |
| 1372 SSL_ShutdownServerSessionIDCacheInstance(cacheDesc *cache) | 1353 SSL_ShutdownServerSessionIDCacheInstance(cacheDesc *cache) |
| 1373 { | 1354 { |
| 1374 CloseCache(cache); | 1355 CloseCache(cache); |
| 1375 return SECSuccess; | 1356 return SECSuccess; |
| 1376 } | 1357 } |
| 1377 | 1358 |
| 1378 SECStatus | 1359 SECStatus |
| 1379 SSL_ShutdownServerSessionIDCache(void) | 1360 SSL_ShutdownServerSessionIDCache(void) |
| 1380 { | 1361 { |
| 1381 #if defined(XP_UNIX) || defined(XP_BEOS) | 1362 #if defined(XP_UNIX) || defined(XP_BEOS) |
| 1382 /* Stop the thread that polls cache for expired locks on Unix */ | 1363 /* Stop the thread that polls cache for expired locks on Unix */ |
| 1383 StopLockPoller(&globalCache); | 1364 StopLockPoller(&globalCache); |
| 1384 #endif | 1365 #endif |
| 1385 SSL3_ShutdownServerCache(); | 1366 SSL3_ShutdownServerCache(); |
| 1386 return SSL_ShutdownServerSessionIDCacheInstance(&globalCache); | 1367 return SSL_ShutdownServerSessionIDCacheInstance(&globalCache); |
| 1387 } | 1368 } |
| 1388 | 1369 |
| 1389 /* Use this function, instead of SSL_ConfigServerSessionIDCache, | 1370 /* Use this function, instead of SSL_ConfigServerSessionIDCache, |
| 1390 * if the cache will be shared by multiple processes. | 1371 * if the cache will be shared by multiple processes. |
| 1391 */ | 1372 */ |
| 1392 static SECStatus | 1373 static SECStatus |
| 1393 ssl_ConfigMPServerSIDCacheWithOpt( PRUint32 ssl2_timeout, | 1374 ssl_ConfigMPServerSIDCacheWithOpt(PRUint32 ssl2_timeout, |
| 1394 PRUint32 ssl3_timeout, | 1375 PRUint32 ssl3_timeout, |
| 1395 const char * directory, | 1376 const char *directory, |
| 1396 int maxCacheEntries, | 1377 int maxCacheEntries, |
| 1397 int maxCertCacheEntries, | 1378 int maxCertCacheEntries, |
| 1398 int maxSrvNameCacheEntries) | 1379 int maxSrvNameCacheEntries) |
| 1399 { | 1380 { |
| 1400 char *» envValue; | 1381 char *envValue; |
| 1401 char *» inhValue; | 1382 char *inhValue; |
| 1402 cacheDesc * cache = &globalCache; | 1383 cacheDesc *cache = &globalCache; |
| 1403 PRUint32 fmStrLen; | 1384 PRUint32 fmStrLen; |
| 1404 SECStatus » result; | 1385 SECStatus result; |
| 1405 PRStatus » prStatus; | 1386 PRStatus prStatus; |
| 1406 SECStatus» putEnvFailed; | 1387 SECStatus putEnvFailed; |
| 1407 inheritance inherit; | 1388 inheritance inherit; |
| 1408 char fmString[PR_FILEMAP_STRING_BUFSIZE]; | 1389 char fmString[PR_FILEMAP_STRING_BUFSIZE]; |
| 1409 | 1390 |
| 1410 isMultiProcess = PR_TRUE; | 1391 isMultiProcess = PR_TRUE; |
| 1411 result = ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache, | 1392 result = ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache, |
| 1412 ssl2_timeout, ssl3_timeout, directory, PR_TRUE, | 1393 ssl2_timeout, ssl3_ti
meout, directory, PR_TRUE, |
| 1413 maxCacheEntries, maxCacheEntries, maxSrvNameCacheEntries); | 1394 maxCacheEntries, maxC
acheEntries, maxSrvNameCacheEntries); |
| 1414 if (result != SECSuccess) | 1395 if (result != SECSuccess) |
| 1415 return result; | 1396 return result; |
| 1416 | 1397 |
| 1417 prStatus = PR_ExportFileMapAsString(cache->cacheMemMap, | 1398 prStatus = PR_ExportFileMapAsString(cache->cacheMemMap, |
| 1418 sizeof fmString, fmString); | 1399 sizeof fmString, fmString); |
| 1419 if ((prStatus != PR_SUCCESS) || !(fmStrLen = strlen(fmString))) { | 1400 if ((prStatus != PR_SUCCESS) || !(fmStrLen = strlen(fmString))) { |
| 1420 » SET_ERROR_CODE | 1401 SET_ERROR_CODE |
| 1421 » return SECFailure; | 1402 return SECFailure; |
| 1422 } | 1403 } |
| 1423 | 1404 |
| 1424 inherit.cacheMemSize» = cache->cacheMemSize; | 1405 inherit.cacheMemSize = cache->cacheMemSize; |
| 1425 inherit.fmStrLen = fmStrLen; | 1406 inherit.fmStrLen = fmStrLen; |
| 1426 | 1407 |
| 1427 inhValue = BTOA_DataToAscii((unsigned char *)&inherit, sizeof inherit); | 1408 inhValue = BTOA_DataToAscii((unsigned char *)&inherit, sizeof inherit); |
| 1428 if (!inhValue || !strlen(inhValue)) { | 1409 if (!inhValue || !strlen(inhValue)) { |
| 1429 » SET_ERROR_CODE | 1410 SET_ERROR_CODE |
| 1430 » return SECFailure; | 1411 return SECFailure; |
| 1431 } | 1412 } |
| 1432 envValue = PR_smprintf("%s,%s", inhValue, fmString); | 1413 envValue = PR_smprintf("%s,%s", inhValue, fmString); |
| 1433 if (!envValue || !strlen(envValue)) { | 1414 if (!envValue || !strlen(envValue)) { |
| 1434 » SET_ERROR_CODE | 1415 SET_ERROR_CODE |
| 1435 » return SECFailure; | 1416 return SECFailure; |
| 1436 } | 1417 } |
| 1437 PORT_Free(inhValue); | 1418 PORT_Free(inhValue); |
| 1438 | 1419 |
| 1439 putEnvFailed = (SECStatus)NSS_PutEnv(envVarName, envValue); | 1420 putEnvFailed = (SECStatus)NSS_PutEnv(envVarName, envValue); |
| 1440 PR_smprintf_free(envValue); | 1421 PR_smprintf_free(envValue); |
| 1441 if (putEnvFailed) { | 1422 if (putEnvFailed) { |
| 1442 SET_ERROR_CODE | 1423 SET_ERROR_CODE |
| 1443 result = SECFailure; | 1424 result = SECFailure; |
| 1444 } | 1425 } |
| 1445 | 1426 |
| 1446 #if defined(XP_UNIX) || defined(XP_BEOS) | 1427 #if defined(XP_UNIX) || defined(XP_BEOS) |
| 1447 /* Launch thread to poll cache for expired locks on Unix */ | 1428 /* Launch thread to poll cache for expired locks on Unix */ |
| 1448 LaunchLockPoller(cache); | 1429 LaunchLockPoller(cache); |
| 1449 #endif | 1430 #endif |
| 1450 return result; | 1431 return result; |
| 1451 } | 1432 } |
| 1452 | 1433 |
| 1453 /* Use this function, instead of SSL_ConfigServerSessionIDCache, | 1434 /* Use this function, instead of SSL_ConfigServerSessionIDCache, |
| 1454 * if the cache will be shared by multiple processes. | 1435 * if the cache will be shared by multiple processes. |
| 1455 */ | 1436 */ |
| 1456 SECStatus | 1437 SECStatus |
| 1457 SSL_ConfigMPServerSIDCache(» int maxCacheEntries, | 1438 SSL_ConfigMPServerSIDCache(int maxCacheEntries, |
| 1458 » » » » PRUint32 ssl2_timeout, | 1439 PRUint32 ssl2_timeout, |
| 1459 » » » »PRUint32 ssl3_timeout, | 1440 PRUint32 ssl3_timeout, |
| 1460 » » const char * directory) | 1441 const char *directory) |
| 1461 { | 1442 { |
| 1462 return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout, | 1443 return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout, |
| 1463 ssl3_timeout, | 1444 ssl3_timeout, |
| 1464 directory, | 1445 directory, |
| 1465 maxCacheEntries, | 1446 maxCacheEntries, |
| 1466 -1, -1); | 1447 -1, -1); |
| 1467 } | 1448 } |
| 1468 | 1449 |
| 1469 SECStatus | 1450 SECStatus |
| 1470 SSL_ConfigServerSessionIDCacheWithOpt( | 1451 SSL_ConfigServerSessionIDCacheWithOpt( |
| 1471 » » » » PRUint32 ssl2_timeout, | 1452 PRUint32 ssl2_timeout, |
| 1472 » » » »PRUint32 ssl3_timeout, | 1453 PRUint32 ssl3_timeout, |
| 1473 const char * directory, | 1454 const char *directory, |
| 1474 int maxCacheEntries, | 1455 int maxCacheEntries, |
| 1475 int maxCertCacheEntries, | 1456 int maxCertCacheEntries, |
| 1476 int maxSrvNameCacheEntries, | 1457 int maxSrvNameCacheEntries, |
| 1477 PRBool enableMPCache) | 1458 PRBool enableMPCache) |
| 1478 { | 1459 { |
| 1479 if (!enableMPCache) { | 1460 if (!enableMPCache) { |
| 1480 ssl_InitSessionCacheLocks(); | 1461 ssl_InitSessionCacheLocks(); |
| 1481 return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache, | 1462 return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache, |
| 1482 ssl2_timeout, ssl3_timeout, directory, PR_FALSE, | 1463 ssl2_timeout, ssl3_
timeout, directory, PR_FALSE, |
| 1483 maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries); | 1464 maxCacheEntries, ma
xCertCacheEntries, maxSrvNameCacheEntries); |
| 1484 } else { | 1465 } else { |
| 1485 return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout, ssl3_timeout, | 1466 return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout, ssl3_timeout, |
| 1486 directory, maxCacheEntries, maxCertCacheEntries, | 1467 directory, maxCacheEntries, max
CertCacheEntries, |
| 1487 maxSrvNameCacheEntries); | 1468 maxSrvNameCacheEntries); |
| 1488 } | 1469 } |
| 1489 } | 1470 } |
| 1490 | 1471 |
| 1491 SECStatus | 1472 SECStatus |
| 1492 SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString) | 1473 SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char *envString) |
| 1493 { | 1474 { |
| 1494 unsigned char * decoString = NULL; | 1475 unsigned char *decoString = NULL; |
| 1495 char * fmString = NULL; | 1476 char *fmString = NULL; |
| 1496 char * myEnvString = NULL; | 1477 char *myEnvString = NULL; |
| 1497 unsigned int decoLen; | 1478 unsigned int decoLen; |
| 1498 inheritance inherit; | 1479 inheritance inherit; |
| 1499 cacheDesc my; | 1480 cacheDesc my; |
| 1500 #ifdef WINNT | 1481 #ifdef WINNT |
| 1501 sidCacheLock* newLocks; | 1482 sidCacheLock *newLocks; |
| 1502 int locks_initialized = 0; | 1483 int locks_initialized = 0; |
| 1503 int locks_to_initialize = 0; | 1484 int locks_to_initialize = 0; |
| 1504 #endif | 1485 #endif |
| 1505 SECStatus status = ssl_Init(); | 1486 SECStatus status = ssl_Init(); |
| 1506 | 1487 |
| 1507 if (status != SECSuccess) { | 1488 if (status != SECSuccess) { |
| 1508 » return status; | 1489 return status; |
| 1509 } | 1490 } |
| 1510 | 1491 |
| 1511 myPid = SSL_GETPID(); | 1492 myPid = SSL_GETPID(); |
| 1512 | 1493 |
| 1513 /* If this child was created by fork(), and not by exec() on unix, | 1494 /* If this child was created by fork(), and not by exec() on unix, |
| 1514 ** then isMultiProcess will already be set. | 1495 ** then isMultiProcess will already be set. |
| 1515 ** If not, we'll set it below. | 1496 ** If not, we'll set it below. |
| 1516 */ | 1497 */ |
| 1517 if (isMultiProcess) { | 1498 if (isMultiProcess) { |
| 1518 » if (cache && cache->sharedCache) { | 1499 if (cache && cache->sharedCache) { |
| 1519 » cache->sharedCache->everInherited = PR_TRUE; | 1500 cache->sharedCache->everInherited = PR_TRUE; |
| 1520 » } | 1501 } |
| 1521 » return SECSuccess;» /* already done. */ | 1502 return SECSuccess; /* already done. */ |
| 1522 } | 1503 } |
| 1523 | 1504 |
| 1524 ssl_InitSessionCacheLocks(); | 1505 ssl_InitSessionCacheLocks(); |
| 1525 | 1506 |
| 1526 ssl_sid_lookup = ServerSessionIDLookup; | 1507 ssl_sid_lookup = ServerSessionIDLookup; |
| 1527 ssl_sid_cache = ServerSessionIDCache; | 1508 ssl_sid_cache = ServerSessionIDCache; |
| 1528 ssl_sid_uncache = ServerSessionIDUncache; | 1509 ssl_sid_uncache = ServerSessionIDUncache; |
| 1529 | 1510 |
| 1530 if (!envString) { | 1511 if (!envString) { |
| 1531 » envString = getenv(envVarName); | 1512 envString = PR_GetEnvSecure(envVarName); |
| 1532 » if (!envString) { | 1513 if (!envString) { |
| 1533 » SET_ERROR_CODE | 1514 SET_ERROR_CODE |
| 1534 » return SECFailure; | 1515 return SECFailure; |
| 1535 » } | 1516 } |
| 1536 } | 1517 } |
| 1537 myEnvString = PORT_Strdup(envString); | 1518 myEnvString = PORT_Strdup(envString); |
| 1538 if (!myEnvString) | 1519 if (!myEnvString) |
| 1539 » return SECFailure; | 1520 return SECFailure; |
| 1540 fmString = strchr(myEnvString, ','); | 1521 fmString = strchr(myEnvString, ','); |
| 1541 if (!fmString) | 1522 if (!fmString) |
| 1542 » goto loser; | 1523 goto loser; |
| 1543 *fmString++ = 0; | 1524 *fmString++ = 0; |
| 1544 | 1525 |
| 1545 decoString = ATOB_AsciiToData(myEnvString, &decoLen); | 1526 decoString = ATOB_AsciiToData(myEnvString, &decoLen); |
| 1546 if (!decoString) { | 1527 if (!decoString) { |
| 1547 » SET_ERROR_CODE | 1528 SET_ERROR_CODE |
| 1548 » goto loser; | 1529 goto loser; |
| 1549 } | 1530 } |
| 1550 if (decoLen != sizeof inherit) { | 1531 if (decoLen != sizeof inherit) { |
| 1551 » SET_ERROR_CODE | 1532 SET_ERROR_CODE |
| 1552 » goto loser; | 1533 goto loser; |
| 1553 } | 1534 } |
| 1554 | 1535 |
| 1555 PORT_Memcpy(&inherit, decoString, sizeof inherit); | 1536 PORT_Memcpy(&inherit, decoString, sizeof inherit); |
| 1556 | 1537 |
| 1557 if (strlen(fmString) != inherit.fmStrLen ) { | 1538 if (strlen(fmString) != inherit.fmStrLen) { |
| 1558 » goto loser; | 1539 goto loser; |
| 1559 } | 1540 } |
| 1560 | 1541 |
| 1561 memset(cache, 0, sizeof *cache); | 1542 memset(cache, 0, sizeof *cache); |
| 1562 cache->cacheMemSize»= inherit.cacheMemSize; | 1543 cache->cacheMemSize = inherit.cacheMemSize; |
| 1563 | 1544 |
| 1564 /* Create cache */ | 1545 /* Create cache */ |
| 1565 cache->cacheMemMap = PR_ImportFileMapFromString(fmString); | 1546 cache->cacheMemMap = PR_ImportFileMapFromString(fmString); |
| 1566 if(! cache->cacheMemMap) { | 1547 if (!cache->cacheMemMap) { |
| 1567 » goto loser; | 1548 goto loser; |
| 1568 } | 1549 } |
| 1569 cache->cacheMem = PR_MemMap(cache->cacheMemMap, 0, cache->cacheMemSize); | 1550 cache->cacheMem = PR_MemMap(cache->cacheMemMap, 0, cache->cacheMemSize); |
| 1570 if (! cache->cacheMem) { | 1551 if (!cache->cacheMem) { |
| 1571 » goto loser; | 1552 goto loser; |
| 1572 } | 1553 } |
| 1573 cache->sharedCache = (cacheDesc *)cache->cacheMem; | 1554 cache->sharedCache = (cacheDesc *)cache->cacheMem; |
| 1574 | 1555 |
| 1575 if (cache->sharedCache->cacheMemSize != cache->cacheMemSize) { | 1556 if (cache->sharedCache->cacheMemSize != cache->cacheMemSize) { |
| 1576 » SET_ERROR_CODE | 1557 SET_ERROR_CODE |
| 1577 » goto loser; | 1558 goto loser; |
| 1578 } | 1559 } |
| 1579 | 1560 |
| 1580 /* We're now going to overwrite the local cache instance with the | 1561 /* We're now going to overwrite the local cache instance with the |
| 1581 ** shared copy of the cache struct, then update several values in | 1562 ** shared copy of the cache struct, then update several values in |
| 1582 ** the local cache using the values for cache->cacheMemMap and | 1563 ** the local cache using the values for cache->cacheMemMap and |
| 1583 ** cache->cacheMem computed just above. So, we copy cache into | 1564 ** cache->cacheMem computed just above. So, we copy cache into |
| 1584 ** the automatic variable "my", to preserve the variables while | 1565 ** the automatic variable "my", to preserve the variables while |
| 1585 ** cache is overwritten. | 1566 ** cache is overwritten. |
| 1586 */ | 1567 */ |
| 1587 my = *cache; /* save values computed above. */ | 1568 my = *cache; /* save values computed ab
ove. */ |
| 1588 memcpy(cache, cache->sharedCache, sizeof *cache); /* overwrite */ | 1569 memcpy(cache, cache->sharedCache, sizeof *cache); /* overwrite */ |
| 1589 | 1570 |
| 1590 /* Fix pointers in our private copy of cache descriptor to point to | 1571 /* Fix pointers in our private copy of cache descriptor to point to |
| 1591 ** spaces in shared memory, whose address is now in "my". | 1572 ** spaces in shared memory, whose address is now in "my". |
| 1592 */ | 1573 */ |
| 1593 cache->sidCacheLocks = (sidCacheLock *) | 1574 cache->sidCacheLocks = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->sidC
acheLocks); |
| 1594 (my.cacheMem + (ptrdiff_t)cache->sidCacheLocks); | 1575 cache->keyCacheLock = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->keyCa
cheLock); |
| 1595 cache->keyCacheLock = (sidCacheLock *) | 1576 cache->certCacheLock = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->cert
CacheLock); |
| 1596 (my.cacheMem + (ptrdiff_t)cache->keyCacheLock); | 1577 cache->srvNameCacheLock = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->s
rvNameCacheLock); |
| 1597 cache->certCacheLock = (sidCacheLock *) | 1578 cache->sidCacheSets = (sidCacheSet *)(my.cacheMem + (ptrdiff_t)cache->sidCac
heSets); |
| 1598 (my.cacheMem + (ptrdiff_t)cache->certCacheLock); | 1579 cache->sidCacheData = (sidCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->sidC
acheData); |
| 1599 cache->srvNameCacheLock = (sidCacheLock *) | 1580 cache->certCacheData = (certCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->ce
rtCacheData); |
| 1600 (my.cacheMem + (ptrdiff_t)cache->srvNameCacheLock); | 1581 cache->keyCacheData = (SSLWrappedSymWrappingKey *)(my.cacheMem + (ptrdiff_t)
cache->keyCacheData); |
| 1601 cache->sidCacheSets = (sidCacheSet *) | 1582 cache->ticketKeyNameSuffix = (PRUint8 *)(my.cacheMem + (ptrdiff_t)cache->tic
ketKeyNameSuffix); |
| 1602 (my.cacheMem + (ptrdiff_t)cache->sidCacheSets); | 1583 cache->ticketEncKey = (encKeyCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->t
icketEncKey); |
| 1603 cache->sidCacheData = (sidCacheEntry *) | 1584 cache->ticketMacKey = (encKeyCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->t
icketMacKey); |
| 1604 (my.cacheMem + (ptrdiff_t)cache->sidCacheData); | 1585 cache->ticketKeysValid = (PRUint32 *)(my.cacheMem + (ptrdiff_t)cache->ticket
KeysValid); |
| 1605 cache->certCacheData = (certCacheEntry *) | 1586 cache->srvNameCacheData = (srvNameCacheEntry *)(my.cacheMem + (ptrdiff_t)cac
he->srvNameCacheData); |
| 1606 (my.cacheMem + (ptrdiff_t)cache->certCacheData); | |
| 1607 cache->keyCacheData = (SSLWrappedSymWrappingKey *) | |
| 1608 (my.cacheMem + (ptrdiff_t)cache->keyCacheData); | |
| 1609 cache->ticketKeyNameSuffix = (PRUint8 *) | |
| 1610 (my.cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix); | |
| 1611 cache->ticketEncKey = (encKeyCacheEntry *) | |
| 1612 (my.cacheMem + (ptrdiff_t)cache->ticketEncKey); | |
| 1613 cache->ticketMacKey = (encKeyCacheEntry *) | |
| 1614 (my.cacheMem + (ptrdiff_t)cache->ticketMacKey); | |
| 1615 cache->ticketKeysValid = (PRUint32 *) | |
| 1616 (my.cacheMem + (ptrdiff_t)cache->ticketKeysValid); | |
| 1617 cache->srvNameCacheData = (srvNameCacheEntry *) | |
| 1618 (my.cacheMem + (ptrdiff_t)cache->srvNameCacheData); | |
| 1619 | 1587 |
| 1620 cache->cacheMemMap = my.cacheMemMap; | 1588 cache->cacheMemMap = my.cacheMemMap; |
| 1621 cache->cacheMem = my.cacheMem; | 1589 cache->cacheMem = my.cacheMem; |
| 1622 cache->sharedCache = (cacheDesc *)cache->cacheMem; | 1590 cache->sharedCache = (cacheDesc *)cache->cacheMem; |
| 1623 | 1591 |
| 1624 #ifdef WINNT | 1592 #ifdef WINNT |
| 1625 /* On Windows NT we need to "fix" the sidCacheLocks here to support fibers | 1593 /* On Windows NT we need to "fix" the sidCacheLocks here to support fibers |
| 1626 ** When NT fibers are used in a multi-process server, a second level of | 1594 ** When NT fibers are used in a multi-process server, a second level of |
| 1627 ** locking is needed to prevent a deadlock, in case a fiber acquires the | 1595 ** locking is needed to prevent a deadlock, in case a fiber acquires the |
| 1628 ** cross-process mutex, yields, and another fiber is later scheduled on | 1596 ** cross-process mutex, yields, and another fiber is later scheduled on |
| 1629 ** the same native thread and tries to acquire the cross-process mutex. | 1597 ** the same native thread and tries to acquire the cross-process mutex. |
| 1630 ** We do this by using a PRLock in the sslMutex. However, it is stored in | 1598 ** We do this by using a PRLock in the sslMutex. However, it is stored in |
| 1631 ** shared memory as part of sidCacheLocks, and we don't want to overwrite | 1599 ** shared memory as part of sidCacheLocks, and we don't want to overwrite |
| 1632 ** the PRLock of the parent process. So we need to make new, private | 1600 ** the PRLock of the parent process. So we need to make new, private |
| 1633 ** copies of sidCacheLocks before modifying the sslMutex with our own | 1601 ** copies of sidCacheLocks before modifying the sslMutex with our own |
| 1634 ** PRLock | 1602 ** PRLock |
| 1635 */ | 1603 */ |
| 1636 | 1604 |
| 1637 /* note from jpierre : this should be free'd in child processes when | 1605 /* note from jpierre : this should be free'd in child processes when |
| 1638 ** a function is added to delete the SSL session cache in the future. | 1606 ** a function is added to delete the SSL session cache in the future. |
| 1639 */ | 1607 */ |
| 1640 locks_to_initialize = cache->numSIDCacheLocks + 3; | 1608 locks_to_initialize = cache->numSIDCacheLocks + 3; |
| 1641 newLocks = PORT_NewArray(sidCacheLock, locks_to_initialize); | 1609 newLocks = PORT_NewArray(sidCacheLock, locks_to_initialize); |
| 1642 if (!newLocks) | 1610 if (!newLocks) |
| 1643 » goto loser; | 1611 goto loser; |
| 1644 /* copy the old locks */ | 1612 /* copy the old locks */ |
| 1645 memcpy(newLocks, cache->sidCacheLocks, | 1613 memcpy(newLocks, cache->sidCacheLocks, |
| 1646 locks_to_initialize * sizeof(sidCacheLock)); | 1614 locks_to_initialize * sizeof(sidCacheLock)); |
| 1647 cache->sidCacheLocks = newLocks; | 1615 cache->sidCacheLocks = newLocks; |
| 1648 /* fix the locks */»» | 1616 /* fix the locks */ |
| 1649 for (; locks_initialized < locks_to_initialize; ++locks_initialized) { | 1617 for (; locks_initialized < locks_to_initialize; ++locks_initialized) { |
| 1650 /* now, make a local PRLock in this sslMutex for this child process */ | 1618 /* now, make a local PRLock in this sslMutex for this child process */ |
| 1651 » SECStatus err; | 1619 SECStatus err; |
| 1652 err = sslMutex_2LevelInit(&newLocks[locks_initialized].mutex); | 1620 err = sslMutex_2LevelInit(&newLocks[locks_initialized].mutex); |
| 1653 » if (err != SECSuccess) { | 1621 if (err != SECSuccess) { |
| 1654 » cache->numSIDCacheLocksInitialized = locks_initialized; | 1622 cache->numSIDCacheLocksInitialized = locks_initialized; |
| 1655 » goto loser; | 1623 goto loser; |
| 1656 » } | 1624 } |
| 1657 } | 1625 } |
| 1658 cache->numSIDCacheLocksInitialized = locks_initialized; | 1626 cache->numSIDCacheLocksInitialized = locks_initialized; |
| 1659 | 1627 |
| 1660 /* also fix the key and cert cache which use the last 2 lock entries */ | 1628 /* also fix the key and cert cache which use the last 2 lock entries */ |
| 1661 cache->keyCacheLock = cache->sidCacheLocks + cache->numSIDCacheLocks; | 1629 cache->keyCacheLock = cache->sidCacheLocks + cache->numSIDCacheLocks; |
| 1662 cache->certCacheLock = cache->keyCacheLock + 1; | 1630 cache->certCacheLock = cache->keyCacheLock + 1; |
| 1663 cache->srvNameCacheLock = cache->certCacheLock + 1; | 1631 cache->srvNameCacheLock = cache->certCacheLock + 1; |
| 1664 #endif | 1632 #endif |
| 1665 | 1633 |
| 1666 PORT_Free(myEnvString); | 1634 PORT_Free(myEnvString); |
| 1667 PORT_Free(decoString); | 1635 PORT_Free(decoString); |
| 1668 | 1636 |
| 1669 /* mark that we have inherited this. */ | 1637 /* mark that we have inherited this. */ |
| 1670 cache->sharedCache->everInherited = PR_TRUE; | 1638 cache->sharedCache->everInherited = PR_TRUE; |
| 1671 isMultiProcess = PR_TRUE; | 1639 isMultiProcess = PR_TRUE; |
| 1672 | 1640 |
| 1673 return SECSuccess; | 1641 return SECSuccess; |
| 1674 | 1642 |
| 1675 loser: | 1643 loser: |
| 1676 PORT_Free(myEnvString); | 1644 PORT_Free(myEnvString); |
| 1677 if (decoString) | 1645 if (decoString) |
| 1678 » PORT_Free(decoString); | 1646 PORT_Free(decoString); |
| 1679 CloseCache(cache); | 1647 CloseCache(cache); |
| 1680 return SECFailure; | 1648 return SECFailure; |
| 1681 } | 1649 } |
| 1682 | 1650 |
| 1683 SECStatus | 1651 SECStatus |
| 1684 SSL_InheritMPServerSIDCache(const char * envString) | 1652 SSL_InheritMPServerSIDCache(const char *envString) |
| 1685 { | 1653 { |
| 1686 return SSL_InheritMPServerSIDCacheInstance(&globalCache, envString); | 1654 return SSL_InheritMPServerSIDCacheInstance(&globalCache, envString); |
| 1687 } | 1655 } |
| 1688 | 1656 |
| 1689 #if defined(XP_UNIX) || defined(XP_BEOS) | 1657 #if defined(XP_UNIX) || defined(XP_BEOS) |
| 1690 | 1658 |
| 1691 #define SID_LOCK_EXPIRATION_TIMEOUT 30 /* seconds */ | 1659 #define SID_LOCK_EXPIRATION_TIMEOUT 30 /* seconds */ |
| 1692 | 1660 |
| 1693 static void | 1661 static void |
| 1694 LockPoller(void * arg) | 1662 LockPoller(void *arg) |
| 1695 { | 1663 { |
| 1696 cacheDesc * cache = (cacheDesc *)arg; | 1664 cacheDesc *cache = (cacheDesc *)arg; |
| 1697 cacheDesc * sharedCache = cache->sharedCache; | 1665 cacheDesc *sharedCache = cache->sharedCache; |
| 1698 sidCacheLock * pLock; | 1666 sidCacheLock *pLock; |
| 1699 PRIntervalTime timeout; | 1667 PRIntervalTime timeout; |
| 1700 PRUint32 now; | 1668 PRUint32 now; |
| 1701 PRUint32 then; | 1669 PRUint32 then; |
| 1702 int locks_polled = 0; | 1670 int locks_polled = 0; |
| 1703 int locks_to_poll = cache->numSIDCacheLocks + 2; | 1671 int locks_to_poll = cache->numSIDCacheLocks + 2; |
| 1704 PRUint32 expiration = cache->mutexTimeout; | 1672 PRUint32 expiration = cache->mutexTimeout; |
| 1705 | 1673 |
| 1706 timeout = PR_SecondsToInterval(expiration); | 1674 timeout = PR_SecondsToInterval(expiration); |
| 1707 while(!sharedCache->stopPolling) { | 1675 while (!sharedCache->stopPolling) { |
| 1708 » PR_Sleep(timeout); | 1676 PR_Sleep(timeout); |
| 1709 » if (sharedCache->stopPolling) | 1677 if (sharedCache->stopPolling) |
| 1710 » break; | 1678 break; |
| 1711 | 1679 |
| 1712 » now = ssl_Time(); | 1680 now = ssl_Time(); |
| 1713 » then = now - expiration; | 1681 then = now - expiration; |
| 1714 » for (pLock = cache->sidCacheLocks, locks_polled = 0; | 1682 for (pLock = cache->sidCacheLocks, locks_polled = 0; |
| 1715 » locks_to_poll > locks_polled && !sharedCache->stopPolling; | 1683 locks_to_poll > locks_polled && !sharedCache->stopPolling; |
| 1716 » ++locks_polled, ++pLock ) { | 1684 ++locks_polled, ++pLock) { |
| 1717 » pid_t pid; | 1685 pid_t pid; |
| 1718 | 1686 |
| 1719 » if (pLock->timeStamp < then && | 1687 if (pLock->timeStamp < then && |
| 1720 » pLock->timeStamp != 0 && | 1688 pLock->timeStamp != 0 && |
| 1721 » » (pid = pLock->pid) != 0) { | 1689 (pid = pLock->pid) != 0) { |
| 1722 | 1690 |
| 1723 » » /* maybe we should try the lock? */ | 1691 /* maybe we should try the lock? */ |
| 1724 » » int result = kill(pid, 0); | 1692 int result = kill(pid, 0); |
| 1725 » » if (result < 0 && errno == ESRCH) { | 1693 if (result < 0 && errno == ESRCH) { |
| 1726 » » SECStatus rv; | 1694 SECStatus rv; |
| 1727 » » /* No process exists by that pid any more. | 1695 /* No process exists by that pid any more. |
| 1728 » » ** Treat this mutex as abandoned. | 1696 ** Treat this mutex as abandoned. |
| 1729 » » */ | 1697 */ |
| 1730 » » pLock->timeStamp = now; | 1698 pLock->timeStamp = now; |
| 1731 » » pLock->pid = 0; | 1699 pLock->pid = 0; |
| 1732 » » rv = sslMutex_Unlock(&pLock->mutex); | 1700 rv = sslMutex_Unlock(&pLock->mutex); |
| 1733 » » if (rv != SECSuccess) { | 1701 if (rv != SECSuccess) { |
| 1734 » » » /* Now what? */ | 1702 /* Now what? */ |
| 1735 » » } | 1703 } |
| 1736 » » } | 1704 } |
| 1737 » } | 1705 } |
| 1738 » } /* end of loop over locks */ | 1706 } /* end of loop over locks */ |
| 1739 } /* end of entire polling loop */ | 1707 } /* end of entire polling loop */ |
| 1740 } | 1708 } |
| 1741 | 1709 |
| 1742 /* Launch thread to poll cache for expired locks */ | 1710 /* Launch thread to poll cache for expired locks */ |
| 1743 static SECStatus | 1711 static SECStatus |
| 1744 LaunchLockPoller(cacheDesc *cache) | 1712 LaunchLockPoller(cacheDesc *cache) |
| 1745 { | 1713 { |
| 1746 const char * timeoutString; | 1714 const char *timeoutString; |
| 1747 PRThread * pollerThread; | 1715 PRThread *pollerThread; |
| 1748 | 1716 |
| 1749 cache->mutexTimeout = SID_LOCK_EXPIRATION_TIMEOUT; | 1717 cache->mutexTimeout = SID_LOCK_EXPIRATION_TIMEOUT; |
| 1750 timeoutString = getenv("NSS_SSL_SERVER_CACHE_MUTEX_TIMEOUT"); | 1718 timeoutString = PR_GetEnvSecure("NSS_SSL_SERVER_CACHE_MUTEX_TIMEOUT"); |
| 1751 if (timeoutString) { | 1719 if (timeoutString) { |
| 1752 » long newTime = strtol(timeoutString, 0, 0); | 1720 long newTime = strtol(timeoutString, 0, 0); |
| 1753 » if (newTime == 0) | 1721 if (newTime == 0) |
| 1754 » return SECSuccess; /* application doesn't want poller thread */ | 1722 return SECSuccess; /* application doesn't want poller thread */ |
| 1755 » if (newTime > 0) | 1723 if (newTime > 0) |
| 1756 » cache->mutexTimeout = (PRUint32)newTime; | 1724 cache->mutexTimeout = (PRUint32)newTime; |
| 1757 » /* if error (newTime < 0) ignore it and use default */ | 1725 /* if error (newTime < 0) ignore it and use default */ |
| 1758 } | 1726 } |
| 1759 | 1727 |
| 1760 pollerThread = | 1728 pollerThread = |
| 1761 » PR_CreateThread(PR_USER_THREAD, LockPoller, cache, PR_PRIORITY_NORMAL, | 1729 PR_CreateThread(PR_USER_THREAD, LockPoller, cache, PR_PRIORITY_NORMAL, |
| 1762 » PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); | 1730 PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); |
| 1763 if (!pollerThread) { | 1731 if (!pollerThread) { |
| 1764 » return SECFailure; | 1732 return SECFailure; |
| 1765 } | 1733 } |
| 1766 cache->poller = pollerThread; | 1734 cache->poller = pollerThread; |
| 1767 return SECSuccess; | 1735 return SECSuccess; |
| 1768 } | 1736 } |
| 1769 | 1737 |
| 1770 /* Stop the thread that polls cache for expired locks */ | 1738 /* Stop the thread that polls cache for expired locks */ |
| 1771 static SECStatus | 1739 static SECStatus |
| 1772 StopLockPoller(cacheDesc *cache) | 1740 StopLockPoller(cacheDesc *cache) |
| 1773 { | 1741 { |
| 1774 if (!cache->poller) { | 1742 if (!cache->poller) { |
| 1775 » return SECSuccess; | 1743 return SECSuccess; |
| 1776 } | 1744 } |
| 1777 cache->sharedCache->stopPolling = PR_TRUE; | 1745 cache->sharedCache->stopPolling = PR_TRUE; |
| 1778 if (PR_Interrupt(cache->poller) != PR_SUCCESS) { | 1746 if (PR_Interrupt(cache->poller) != PR_SUCCESS) { |
| 1779 » return SECFailure; | 1747 return SECFailure; |
| 1780 } | 1748 } |
| 1781 if (PR_JoinThread(cache->poller) != PR_SUCCESS) { | 1749 if (PR_JoinThread(cache->poller) != PR_SUCCESS) { |
| 1782 » return SECFailure; | 1750 return SECFailure; |
| 1783 } | 1751 } |
| 1784 cache->poller = NULL; | 1752 cache->poller = NULL; |
| 1785 return SECSuccess; | 1753 return SECSuccess; |
| 1786 } | 1754 } |
| 1787 #endif | 1755 #endif |
| 1788 | 1756 |
| 1789 /************************************************************************ | 1757 /************************************************************************ |
| 1790 * Code dealing with shared wrapped symmetric wrapping keys below * | 1758 * Code dealing with shared wrapped symmetric wrapping keys below * |
| 1791 ************************************************************************/ | 1759 ************************************************************************/ |
| 1792 | 1760 |
| 1793 /* If now is zero, it implies that the lock is not held, and must be | 1761 /* If now is zero, it implies that the lock is not held, and must be |
| 1794 ** aquired here. | 1762 ** aquired here. |
| 1795 */ | 1763 */ |
| 1796 static PRBool | 1764 static PRBool |
| 1797 getSvrWrappingKey(PRInt32 symWrapMechIndex, | 1765 getSvrWrappingKey(PRInt32 symWrapMechIndex, |
| 1798 SSL3KEAType exchKeyType, | 1766 SSL3KEAType exchKeyType, |
| 1799 SSLWrappedSymWrappingKey *wswk, | 1767 SSLWrappedSymWrappingKey *wswk, |
| 1800 » cacheDesc * cache, | 1768 cacheDesc *cache, |
| 1801 » PRUint32 lockTime) | 1769 PRUint32 lockTime) |
| 1802 { | 1770 { |
| 1803 PRUint32 ndx = (exchKeyType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex; | 1771 PRUint32 ndx = (exchKeyType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex; |
| 1804 SSLWrappedSymWrappingKey * pwswk = cache->keyCacheData + ndx; | 1772 SSLWrappedSymWrappingKey *pwswk = cache->keyCacheData + ndx; |
| 1805 PRUint32 now = 0; | 1773 PRUint32 now = 0; |
| 1806 PRBool rv = PR_FALSE; | 1774 PRBool rv = PR_FALSE; |
| 1807 | 1775 |
| 1808 if (!cache->cacheMem) { /* cache is uninitialized */ | 1776 if (!cache->cacheMem) { /* cache is uninitialized */ |
| 1809 » PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED); | 1777 PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED); |
| 1810 » return rv; | 1778 return rv; |
| 1811 } | 1779 } |
| 1812 if (!lockTime) { | 1780 if (!lockTime) { |
| 1813 » lockTime = now = LockSidCacheLock(cache->keyCacheLock, now); | 1781 lockTime = now = LockSidCacheLock(cache->keyCacheLock, now); |
| 1814 » if (!lockTime) { | 1782 if (!lockTime) { |
| 1815 » return rv; | 1783 return rv; |
| 1816 » } | 1784 } |
| 1817 } | 1785 } |
| 1818 if (pwswk->exchKeyType == exchKeyType && | 1786 if (pwswk->exchKeyType == exchKeyType && |
| 1819 » pwswk->symWrapMechIndex == symWrapMechIndex && | 1787 pwswk->symWrapMechIndex == symWrapMechIndex && |
| 1820 » pwswk->wrappedSymKeyLen != 0) { | 1788 pwswk->wrappedSymKeyLen != 0) { |
| 1821 » *wswk = *pwswk; | 1789 *wswk = *pwswk; |
| 1822 » rv = PR_TRUE; | 1790 rv = PR_TRUE; |
| 1823 } | 1791 } |
| 1824 if (now) { | 1792 if (now) { |
| 1825 » UnlockSidCacheLock(cache->keyCacheLock); | 1793 UnlockSidCacheLock(cache->keyCacheLock); |
| 1826 } | 1794 } |
| 1827 return rv; | 1795 return rv; |
| 1828 } | 1796 } |
| 1829 | 1797 |
| 1830 PRBool | 1798 PRBool |
| 1831 ssl_GetWrappingKey( PRInt32 symWrapMechIndex, | 1799 ssl_GetWrappingKey(PRInt32 symWrapMechIndex, |
| 1832 SSL3KEAType exchKeyType, | 1800 SSL3KEAType exchKeyType, |
| 1833 » » SSLWrappedSymWrappingKey *wswk) | 1801 SSLWrappedSymWrappingKey *wswk) |
| 1834 { | 1802 { |
| 1835 PRBool rv; | 1803 PRBool rv; |
| 1836 | 1804 |
| 1837 PORT_Assert( (unsigned)exchKeyType < kt_kea_size); | 1805 PORT_Assert((unsigned)exchKeyType < kt_kea_size); |
| 1838 PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS); | 1806 PORT_Assert((unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS); |
| 1839 if ((unsigned)exchKeyType < kt_kea_size && | 1807 if ((unsigned)exchKeyType < kt_kea_size && |
| 1840 (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS) { | 1808 (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS) { |
| 1841 » rv = getSvrWrappingKey(symWrapMechIndex, exchKeyType, wswk, | 1809 rv = getSvrWrappingKey(symWrapMechIndex, exchKeyType, wswk, |
| 1842 » &globalCache, 0); | 1810 &globalCache, 0); |
| 1843 } else { | 1811 } else { |
| 1844 » rv = PR_FALSE; | 1812 rv = PR_FALSE; |
| 1845 } | 1813 } |
| 1846 | 1814 |
| 1847 return rv; | 1815 return rv; |
| 1848 } | 1816 } |
| 1849 | 1817 |
| 1850 /* Wrap and cache a session ticket key. */ | 1818 /* Wrap and cache a session ticket key. */ |
| 1851 static PRBool | 1819 static PRBool |
| 1852 WrapTicketKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey, | 1820 WrapTicketKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey, |
| 1853 const char *keyName, encKeyCacheEntry* cacheEntry) | 1821 const char *keyName, encKeyCacheEntry *cacheEntry) |
| 1854 { | 1822 { |
| 1855 SECItem wrappedKey = {siBuffer, NULL, 0}; | 1823 SECItem wrappedKey = { siBuffer, NULL, 0 }; |
| 1856 | 1824 |
| 1857 wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey); | 1825 wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey); |
| 1858 PORT_Assert(wrappedKey.len <= sizeof(cacheEntry->bytes)); | 1826 PORT_Assert(wrappedKey.len <= sizeof(cacheEntry->bytes)); |
| 1859 if (wrappedKey.len > sizeof(cacheEntry->bytes)) | 1827 if (wrappedKey.len > sizeof(cacheEntry->bytes)) |
| 1860 » return PR_FALSE; | 1828 return PR_FALSE; |
| 1861 wrappedKey.data = cacheEntry->bytes; | 1829 wrappedKey.data = cacheEntry->bytes; |
| 1862 | 1830 |
| 1863 if (PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, symKey, &wrappedKey) | 1831 if (PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, symKey, &wrappedKey) != |
| 1864 » != SECSuccess) { | 1832 SECSuccess) { |
| 1865 » SSL_DBG(("%d: SSL[%s]: Unable to wrap session ticket %s.", | 1833 SSL_DBG(("%d: SSL[%s]: Unable to wrap session ticket %s.", |
| 1866 » » SSL_GETPID(), "unknown", keyName)); | 1834 SSL_GETPID(), "unknown", keyName)); |
| 1867 » return PR_FALSE; | 1835 return PR_FALSE; |
| 1868 } | 1836 } |
| 1869 cacheEntry->length = wrappedKey.len; | 1837 cacheEntry->length = wrappedKey.len; |
| 1870 return PR_TRUE; | 1838 return PR_TRUE; |
| 1871 } | 1839 } |
| 1872 | 1840 |
| 1873 static PRBool | 1841 static PRBool |
| 1874 GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey, | 1842 GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey, |
| 1875 PK11SymKey **macKey) | 1843 PK11SymKey **macKey) |
| 1876 { | 1844 { |
| 1877 PK11SlotInfo *slot; | 1845 PK11SlotInfo *slot; |
| 1878 CK_MECHANISM_TYPE mechanismArray[2]; | 1846 CK_MECHANISM_TYPE mechanismArray[2]; |
| 1879 PK11SymKey *aesKeyTmp = NULL; | 1847 PK11SymKey *aesKeyTmp = NULL; |
| 1880 PK11SymKey *macKeyTmp = NULL; | 1848 PK11SymKey *macKeyTmp = NULL; |
| 1881 cacheDesc *cache = &globalCache; | 1849 cacheDesc *cache = &globalCache; |
| 1882 PRUint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN]; | 1850 PRUint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN]; |
| 1883 PRUint8 *ticketKeyNameSuffix; | 1851 PRUint8 *ticketKeyNameSuffix; |
| 1884 | 1852 |
| 1885 if (!cache->cacheMem) { | 1853 if (!cache->cacheMem) { |
| 1886 /* cache is not initalized. Use stack buffer */ | 1854 /* cache is not initalized. Use stack buffer */ |
| 1887 ticketKeyNameSuffix = ticketKeyNameSuffixLocal; | 1855 ticketKeyNameSuffix = ticketKeyNameSuffixLocal; |
| 1888 } else { | 1856 } else { |
| 1889 ticketKeyNameSuffix = cache->ticketKeyNameSuffix; | 1857 ticketKeyNameSuffix = cache->ticketKeyNameSuffix; |
| 1890 } | 1858 } |
| 1891 | 1859 |
| 1892 if (PK11_GenerateRandom(ticketKeyNameSuffix, | 1860 if (PK11_GenerateRandom(ticketKeyNameSuffix, |
| 1893 » SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess) { | 1861 SESS_TICKET_KEY_VAR_NAME_LEN) != |
| 1894 » SSL_DBG(("%d: SSL[%s]: Unable to generate random key name bytes.", | 1862 SECSuccess) { |
| 1895 » » SSL_GETPID(), "unknown")); | 1863 SSL_DBG(("%d: SSL[%s]: Unable to generate random key name bytes.", |
| 1896 » goto loser; | 1864 SSL_GETPID(), "unknown")); |
| 1865 goto loser; |
| 1897 } | 1866 } |
| 1898 | 1867 |
| 1899 mechanismArray[0] = CKM_AES_CBC; | 1868 mechanismArray[0] = CKM_AES_CBC; |
| 1900 mechanismArray[1] = CKM_SHA256_HMAC; | 1869 mechanismArray[1] = CKM_SHA256_HMAC; |
| 1901 | 1870 |
| 1902 slot = PK11_GetBestSlotMultiple(mechanismArray, 2, pwArg); | 1871 slot = PK11_GetBestSlotMultiple(mechanismArray, 2, pwArg); |
| 1903 if (slot) { | 1872 if (slot) { |
| 1904 » aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL, | 1873 aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL, |
| 1905 AES_256_KEY_LENGTH, pwArg); | 1874 AES_256_KEY_LENGTH, pwArg); |
| 1906 » macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL, | 1875 macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL, |
| 1907 SHA256_LENGTH, pwArg); | 1876 SHA256_LENGTH, pwArg); |
| 1908 » PK11_FreeSlot(slot); | 1877 PK11_FreeSlot(slot); |
| 1909 } | 1878 } |
| 1910 | 1879 |
| 1911 if (aesKeyTmp == NULL || macKeyTmp == NULL) { | 1880 if (aesKeyTmp == NULL || macKeyTmp == NULL) { |
| 1912 » SSL_DBG(("%d: SSL[%s]: Unable to generate session ticket keys.", | 1881 SSL_DBG(("%d: SSL[%s]: Unable to generate session ticket keys.", |
| 1913 » » SSL_GETPID(), "unknown")); | 1882 SSL_GETPID(), "unknown")); |
| 1914 » goto loser; | 1883 goto loser; |
| 1915 } | 1884 } |
| 1916 PORT_Memcpy(keyName, ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN); | 1885 PORT_Memcpy(keyName, ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN); |
| 1917 *aesKey = aesKeyTmp; | 1886 *aesKey = aesKeyTmp; |
| 1918 *macKey = macKeyTmp; | 1887 *macKey = macKeyTmp; |
| 1919 return PR_TRUE; | 1888 return PR_TRUE; |
| 1920 | 1889 |
| 1921 loser: | 1890 loser: |
| 1922 if (aesKeyTmp) | 1891 if (aesKeyTmp) |
| 1923 » PK11_FreeSymKey(aesKeyTmp); | 1892 PK11_FreeSymKey(aesKeyTmp); |
| 1924 if (macKeyTmp) | 1893 if (macKeyTmp) |
| 1925 » PK11_FreeSymKey(macKeyTmp); | 1894 PK11_FreeSymKey(macKeyTmp); |
| 1926 return PR_FALSE; | 1895 return PR_FALSE; |
| 1927 } | 1896 } |
| 1928 | 1897 |
| 1929 static PRBool | 1898 static PRBool |
| 1930 GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg, | 1899 GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg, |
| 1931 unsigned char *keyName, PK11SymKey **aesKey, | 1900 unsigned char *keyName, PK11SymKey **aesKey, |
| 1932 PK11SymKey **macKey) | 1901 PK11SymKey **macKey) |
| 1933 { | 1902 { |
| 1934 PK11SymKey *aesKeyTmp = NULL; | 1903 PK11SymKey *aesKeyTmp = NULL; |
| 1935 PK11SymKey *macKeyTmp = NULL; | 1904 PK11SymKey *macKeyTmp = NULL; |
| 1936 cacheDesc *cache = &globalCache; | 1905 cacheDesc *cache = &globalCache; |
| 1937 | 1906 |
| 1938 if (!GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp)) { | 1907 if (!GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp)) { |
| 1939 goto loser; | 1908 goto loser; |
| 1940 } | 1909 } |
| 1941 | 1910 |
| 1942 if (cache->cacheMem) { | 1911 if (cache->cacheMem) { |
| 1943 /* Export the keys to the shared cache in wrapped form. */ | 1912 /* Export the keys to the shared cache in wrapped form. */ |
| 1944 if (!WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey)
) | 1913 if (!WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey)
) |
| 1945 goto loser; | 1914 goto loser; |
| 1946 if (!WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey)
) | 1915 if (!WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey)
) |
| 1947 goto loser; | 1916 goto loser; |
| 1948 } | 1917 } |
| 1949 *aesKey = aesKeyTmp; | 1918 *aesKey = aesKeyTmp; |
| 1950 *macKey = macKeyTmp; | 1919 *macKey = macKeyTmp; |
| 1951 return PR_TRUE; | 1920 return PR_TRUE; |
| 1952 | 1921 |
| 1953 loser: | 1922 loser: |
| 1954 if (aesKeyTmp) | 1923 if (aesKeyTmp) |
| 1955 » PK11_FreeSymKey(aesKeyTmp); | 1924 PK11_FreeSymKey(aesKeyTmp); |
| 1956 if (macKeyTmp) | 1925 if (macKeyTmp) |
| 1957 » PK11_FreeSymKey(macKeyTmp); | 1926 PK11_FreeSymKey(macKeyTmp); |
| 1958 return PR_FALSE; | 1927 return PR_FALSE; |
| 1959 } | 1928 } |
| 1960 | 1929 |
| 1961 static PRBool | 1930 static PRBool |
| 1962 UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *keyName, | 1931 UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *keyName, |
| 1963 PK11SymKey **aesKey, PK11SymKey **macKey) | 1932 PK11SymKey **aesKey, PK11SymKey **macKey) |
| 1964 { | 1933 { |
| 1965 SECItem wrappedKey = {siBuffer, NULL, 0}; | 1934 SECItem wrappedKey = { siBuffer, NULL, 0 }; |
| 1966 PK11SymKey *aesKeyTmp = NULL; | 1935 PK11SymKey *aesKeyTmp = NULL; |
| 1967 PK11SymKey *macKeyTmp = NULL; | 1936 PK11SymKey *macKeyTmp = NULL; |
| 1968 cacheDesc *cache = &globalCache; | 1937 cacheDesc *cache = &globalCache; |
| 1969 | 1938 |
| 1970 wrappedKey.data = cache->ticketEncKey->bytes; | 1939 wrappedKey.data = cache->ticketEncKey->bytes; |
| 1971 wrappedKey.len = cache->ticketEncKey->length; | 1940 wrappedKey.len = cache->ticketEncKey->length; |
| 1972 PORT_Assert(wrappedKey.len <= sizeof(cache->ticketEncKey->bytes)); | 1941 PORT_Assert(wrappedKey.len <= sizeof(cache->ticketEncKey->bytes)); |
| 1973 aesKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey, | 1942 aesKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey, |
| 1974 » CKM_AES_CBC, CKA_DECRYPT, 0); | 1943 CKM_AES_CBC, CKA_DECRYPT, 0); |
| 1975 | 1944 |
| 1976 wrappedKey.data = cache->ticketMacKey->bytes; | 1945 wrappedKey.data = cache->ticketMacKey->bytes; |
| 1977 wrappedKey.len = cache->ticketMacKey->length; | 1946 wrappedKey.len = cache->ticketMacKey->length; |
| 1978 PORT_Assert(wrappedKey.len <= sizeof(cache->ticketMacKey->bytes)); | 1947 PORT_Assert(wrappedKey.len <= sizeof(cache->ticketMacKey->bytes)); |
| 1979 macKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey, | 1948 macKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey, |
| 1980 » CKM_SHA256_HMAC, CKA_SIGN, 0); | 1949 CKM_SHA256_HMAC, CKA_SIGN, 0); |
| 1981 | 1950 |
| 1982 if (aesKeyTmp == NULL || macKeyTmp == NULL) { | 1951 if (aesKeyTmp == NULL || macKeyTmp == NULL) { |
| 1983 » SSL_DBG(("%d: SSL[%s]: Unable to unwrap session ticket keys.", | 1952 SSL_DBG(("%d: SSL[%s]: Unable to unwrap session ticket keys.", |
| 1984 » » SSL_GETPID(), "unknown")); | 1953 SSL_GETPID(), "unknown")); |
| 1985 » goto loser; | 1954 goto loser; |
| 1986 } | 1955 } |
| 1987 SSL_DBG(("%d: SSL[%s]: Successfully unwrapped session ticket keys.", | 1956 SSL_DBG(("%d: SSL[%s]: Successfully unwrapped session ticket keys.", |
| 1988 » » SSL_GETPID(), "unknown")); | 1957 SSL_GETPID(), "unknown")); |
| 1989 | 1958 |
| 1990 PORT_Memcpy(keyName, cache->ticketKeyNameSuffix, | 1959 PORT_Memcpy(keyName, cache->ticketKeyNameSuffix, |
| 1991 » SESS_TICKET_KEY_VAR_NAME_LEN); | 1960 SESS_TICKET_KEY_VAR_NAME_LEN); |
| 1992 *aesKey = aesKeyTmp; | 1961 *aesKey = aesKeyTmp; |
| 1993 *macKey = macKeyTmp; | 1962 *macKey = macKeyTmp; |
| 1994 return PR_TRUE; | 1963 return PR_TRUE; |
| 1995 | 1964 |
| 1996 loser: | 1965 loser: |
| 1997 if (aesKeyTmp) | 1966 if (aesKeyTmp) |
| 1998 » PK11_FreeSymKey(aesKeyTmp); | 1967 PK11_FreeSymKey(aesKeyTmp); |
| 1999 if (macKeyTmp) | 1968 if (macKeyTmp) |
| 2000 » PK11_FreeSymKey(macKeyTmp); | 1969 PK11_FreeSymKey(macKeyTmp); |
| 2001 return PR_FALSE; | 1970 return PR_FALSE; |
| 2002 } | 1971 } |
| 2003 | 1972 |
| 2004 PRBool | 1973 PRBool |
| 2005 ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey, | 1974 ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey, |
| 2006 SECKEYPublicKey *svrPubKey, void *pwArg, | 1975 SECKEYPublicKey *svrPubKey, void *pwArg, |
| 2007 unsigned char *keyName, PK11SymKey **aesKey, | 1976 unsigned char *keyName, PK11SymKey **aesKey, |
| 2008 PK11SymKey **macKey) | 1977 PK11SymKey **macKey) |
| 2009 { | 1978 { |
| 2010 PRUint32 now = 0; | 1979 PRUint32 now = 0; |
| 2011 PRBool rv = PR_FALSE; | 1980 PRBool rv = PR_FALSE; |
| 2012 PRBool keysGenerated = PR_FALSE; | 1981 PRBool keysGenerated = PR_FALSE; |
| 2013 cacheDesc *cache = &globalCache; | 1982 cacheDesc *cache = &globalCache; |
| 2014 | 1983 |
| 2015 if (!cache->cacheMem) { | 1984 if (!cache->cacheMem) { |
| 2016 /* cache is uninitialized. Generate keys and return them | 1985 /* cache is uninitialized. Generate keys and return them |
| 2017 * without caching. */ | 1986 * without caching. */ |
| 2018 return GenerateTicketKeys(pwArg, keyName, aesKey, macKey); | 1987 return GenerateTicketKeys(pwArg, keyName, aesKey, macKey); |
| 2019 } | 1988 } |
| 2020 | 1989 |
| 2021 now = LockSidCacheLock(cache->keyCacheLock, now); | 1990 now = LockSidCacheLock(cache->keyCacheLock, now); |
| 2022 if (!now) | 1991 if (!now) |
| 2023 » return rv; | 1992 return rv; |
| 2024 | 1993 |
| 2025 if (!*(cache->ticketKeysValid)) { | 1994 if (!*(cache->ticketKeysValid)) { |
| 2026 » /* Keys do not exist, create them. */ | 1995 /* Keys do not exist, create them. */ |
| 2027 » if (!GenerateAndWrapTicketKeys(svrPubKey, pwArg, keyName, | 1996 if (!GenerateAndWrapTicketKeys(svrPubKey, pwArg, keyName, |
| 2028 » » aesKey, macKey)) | 1997 aesKey, macKey)) |
| 2029 » goto loser; | 1998 goto loser; |
| 2030 » keysGenerated = PR_TRUE; | 1999 keysGenerated = PR_TRUE; |
| 2031 » *(cache->ticketKeysValid) = 1; | 2000 *(cache->ticketKeysValid) = 1; |
| 2032 } | 2001 } |
| 2033 | 2002 |
| 2034 rv = PR_TRUE; | 2003 rv = PR_TRUE; |
| 2035 | 2004 |
| 2036 loser: | 2005 loser: |
| 2037 UnlockSidCacheLock(cache->keyCacheLock); | 2006 UnlockSidCacheLock(cache->keyCacheLock); |
| 2038 if (rv && !keysGenerated) | 2007 if (rv && !keysGenerated) |
| 2039 » rv = UnwrapCachedTicketKeys(svrPrivKey, keyName, aesKey, macKey); | 2008 rv = UnwrapCachedTicketKeys(svrPrivKey, keyName, aesKey, macKey); |
| 2040 return rv; | 2009 return rv; |
| 2041 } | 2010 } |
| 2042 | 2011 |
| 2043 PRBool | 2012 PRBool |
| 2044 ssl_GetSessionTicketKeys(unsigned char *keyName, unsigned char *encKey, | 2013 ssl_GetSessionTicketKeys(unsigned char *keyName, unsigned char *encKey, |
| 2045 unsigned char *macKey) | 2014 unsigned char *macKey) |
| 2046 { | 2015 { |
| 2047 PRBool rv = PR_FALSE; | 2016 PRBool rv = PR_FALSE; |
| 2048 PRUint32 now = 0; | 2017 PRUint32 now = 0; |
| 2049 cacheDesc *cache = &globalCache; | 2018 cacheDesc *cache = &globalCache; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2067 | 2036 |
| 2068 if (cacheIsEnabled) { | 2037 if (cacheIsEnabled) { |
| 2069 /* Grab lock if initialized. */ | 2038 /* Grab lock if initialized. */ |
| 2070 now = LockSidCacheLock(cache->keyCacheLock, now); | 2039 now = LockSidCacheLock(cache->keyCacheLock, now); |
| 2071 if (!now) | 2040 if (!now) |
| 2072 return rv; | 2041 return rv; |
| 2073 } | 2042 } |
| 2074 /* Going to regenerate keys on every call if cache was not | 2043 /* Going to regenerate keys on every call if cache was not |
| 2075 * initialized. */ | 2044 * initialized. */ |
| 2076 if (!cacheIsEnabled || !*(cache->ticketKeysValid)) { | 2045 if (!cacheIsEnabled || !*(cache->ticketKeysValid)) { |
| 2077 » if (PK11_GenerateRandom(ticketKeyNameSuffix, | 2046 if (PK11_GenerateRandom(ticketKeyNameSuffix, |
| 2078 » » SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess) | 2047 SESS_TICKET_KEY_VAR_NAME_LEN) != |
| 2079 » goto loser; | 2048 SECSuccess) |
| 2080 » if (PK11_GenerateRandom(ticketEncKeyPtr, | 2049 goto loser; |
| 2050 if (PK11_GenerateRandom(ticketEncKeyPtr, |
| 2081 AES_256_KEY_LENGTH) != SECSuccess) | 2051 AES_256_KEY_LENGTH) != SECSuccess) |
| 2082 » goto loser; | 2052 goto loser; |
| 2083 » if (PK11_GenerateRandom(ticketMacKeyPtr, | 2053 if (PK11_GenerateRandom(ticketMacKeyPtr, |
| 2084 SHA256_LENGTH) != SECSuccess) | 2054 SHA256_LENGTH) != SECSuccess) |
| 2085 » goto loser; | 2055 goto loser; |
| 2086 if (cacheIsEnabled) { | 2056 if (cacheIsEnabled) { |
| 2087 *(cache->ticketKeysValid) = 1; | 2057 *(cache->ticketKeysValid) = 1; |
| 2088 } | 2058 } |
| 2089 } | 2059 } |
| 2090 | 2060 |
| 2091 rv = PR_TRUE; | 2061 rv = PR_TRUE; |
| 2092 | 2062 |
| 2093 loser: | 2063 loser: |
| 2094 if (cacheIsEnabled) { | 2064 if (cacheIsEnabled) { |
| 2095 UnlockSidCacheLock(cache->keyCacheLock); | 2065 UnlockSidCacheLock(cache->keyCacheLock); |
| 2096 } | 2066 } |
| 2097 if (rv) { | 2067 if (rv) { |
| 2098 » PORT_Memcpy(keyName, ticketKeyNameSuffix, | 2068 PORT_Memcpy(keyName, ticketKeyNameSuffix, |
| 2099 SESS_TICKET_KEY_VAR_NAME_LEN); | 2069 SESS_TICKET_KEY_VAR_NAME_LEN); |
| 2100 » PORT_Memcpy(encKey, ticketEncKeyPtr, AES_256_KEY_LENGTH); | 2070 PORT_Memcpy(encKey, ticketEncKeyPtr, AES_256_KEY_LENGTH); |
| 2101 » PORT_Memcpy(macKey, ticketMacKeyPtr, SHA256_LENGTH); | 2071 PORT_Memcpy(macKey, ticketMacKeyPtr, SHA256_LENGTH); |
| 2102 } | 2072 } |
| 2103 return rv; | 2073 return rv; |
| 2104 } | 2074 } |
| 2105 | 2075 |
| 2106 /* The caller passes in the new value it wants | 2076 /* The caller passes in the new value it wants |
| 2107 * to set. This code tests the wrapped sym key entry in the shared memory. | 2077 * to set. This code tests the wrapped sym key entry in the shared memory. |
| 2108 * If it is uninitialized, this function writes the caller's value into | 2078 * If it is uninitialized, this function writes the caller's value into |
| 2109 * the disk entry, and returns false. | 2079 * the disk entry, and returns false. |
| 2110 * Otherwise, it overwrites the caller's wswk with the value obtained from | 2080 * Otherwise, it overwrites the caller's wswk with the value obtained from |
| 2111 * the disk, and returns PR_TRUE. | 2081 * the disk, and returns PR_TRUE. |
| 2112 * This is all done while holding the locks/mutexes necessary to make | 2082 * This is all done while holding the locks/mutexes necessary to make |
| 2113 * the operation atomic. | 2083 * the operation atomic. |
| 2114 */ | 2084 */ |
| 2115 PRBool | 2085 PRBool |
| 2116 ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk) | 2086 ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk) |
| 2117 { | 2087 { |
| 2118 cacheDesc * cache = &globalCache; | 2088 cacheDesc *cache = &globalCache; |
| 2119 PRBool rv = PR_FALSE; | 2089 PRBool rv = PR_FALSE; |
| 2120 SSL3KEAType exchKeyType = wswk->exchKeyType; | 2090 SSL3KEAType exchKeyType = wswk->exchKeyType; |
| 2121 /* type of keys used to wrap SymWrapKey*/ | 2091 /* type of keys used to wrap SymWrapKey*/ |
| 2122 PRInt32 symWrapMechIndex = wswk->symWrapMechIndex; | 2092 PRInt32 symWrapMechIndex = wswk->symWrapMechIndex; |
| 2123 PRUint32 ndx; | 2093 PRUint32 ndx; |
| 2124 PRUint32 now = 0; | 2094 PRUint32 now = 0; |
| 2125 SSLWrappedSymWrappingKey myWswk; | 2095 SSLWrappedSymWrappingKey myWswk; |
| 2126 | 2096 |
| 2127 if (!cache->cacheMem) { /* cache is uninitialized */ | 2097 if (!cache->cacheMem) { /* cache is uninitialized */ |
| 2128 » PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED); | 2098 PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED); |
| 2129 » return 0; | 2099 return 0; |
| 2130 } | 2100 } |
| 2131 | 2101 |
| 2132 PORT_Assert( (unsigned)exchKeyType < kt_kea_size); | 2102 PORT_Assert((unsigned)exchKeyType < kt_kea_size); |
| 2133 if ((unsigned)exchKeyType >= kt_kea_size) | 2103 if ((unsigned)exchKeyType >= kt_kea_size) |
| 2134 » return 0; | 2104 return 0; |
| 2135 | 2105 |
| 2136 PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS); | 2106 PORT_Assert((unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS); |
| 2137 if ((unsigned)symWrapMechIndex >= SSL_NUM_WRAP_MECHS) | 2107 if ((unsigned)symWrapMechIndex >= SSL_NUM_WRAP_MECHS) |
| 2138 » return 0; | 2108 return 0; |
| 2139 | 2109 |
| 2140 ndx = (exchKeyType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex; | 2110 ndx = (exchKeyType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex; |
| 2141 PORT_Memset(&myWswk, 0, sizeof myWswk);» /* eliminate UMRs. */ | 2111 PORT_Memset(&myWswk, 0, sizeof myWswk); /* eliminate UMRs. */ |
| 2142 | 2112 |
| 2143 now = LockSidCacheLock(cache->keyCacheLock, now); | 2113 now = LockSidCacheLock(cache->keyCacheLock, now); |
| 2144 if (now) { | 2114 if (now) { |
| 2145 » rv = getSvrWrappingKey(wswk->symWrapMechIndex, wswk->exchKeyType, | 2115 rv = getSvrWrappingKey(wswk->symWrapMechIndex, wswk->exchKeyType, |
| 2146 » &myWswk, cache, now); | 2116 &myWswk, cache, now); |
| 2147 » if (rv) { | 2117 if (rv) { |
| 2148 » /* we found it on disk, copy it out to the caller. */ | 2118 /* we found it on disk, copy it out to the caller. */ |
| 2149 » PORT_Memcpy(wswk, &myWswk, sizeof *wswk); | 2119 PORT_Memcpy(wswk, &myWswk, sizeof *wswk); |
| 2150 » } else { | 2120 } else { |
| 2151 » /* Wasn't on disk, and we're still holding the lock, so write it. */ | 2121 /* Wasn't on disk, and we're still holding the lock, so write it. */ |
| 2152 » cache->keyCacheData[ndx] = *wswk; | 2122 cache->keyCacheData[ndx] = *wswk; |
| 2153 » } | 2123 } |
| 2154 » UnlockSidCacheLock(cache->keyCacheLock); | 2124 UnlockSidCacheLock(cache->keyCacheLock); |
| 2155 } | 2125 } |
| 2156 return rv; | 2126 return rv; |
| 2157 } | 2127 } |
| 2158 | 2128 |
| 2159 #else /* MAC version or other platform */ | 2129 #else /* MAC version or other platform */ |
| 2160 | 2130 |
| 2161 #include "seccomon.h" | 2131 #include "seccomon.h" |
| 2162 #include "cert.h" | 2132 #include "cert.h" |
| 2163 #include "ssl.h" | 2133 #include "ssl.h" |
| 2164 #include "sslimpl.h" | 2134 #include "sslimpl.h" |
| 2165 | 2135 |
| 2166 SECStatus | 2136 SECStatus |
| 2167 SSL_ConfigServerSessionIDCache(»int maxCacheEntries, | 2137 SSL_ConfigServerSessionIDCache(int maxCacheEntries, |
| 2168 » » » » PRUint32 ssl2_timeout, | 2138 PRUint32 ssl2_timeout, |
| 2169 » » » »PRUint32 ssl3_timeout, | 2139 PRUint32 ssl3_timeout, |
| 2170 » » » const char * directory) | 2140 const char *directory) |
| 2171 { | 2141 { |
| 2172 PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigServe
rSessionIDCache)"); | 2142 PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigServe
rSessionIDCache)"); |
| 2173 return SECFailure; | 2143 return SECFailure; |
| 2174 } | 2144 } |
| 2175 | 2145 |
| 2176 SECStatus | 2146 SECStatus |
| 2177 SSL_ConfigMPServerSIDCache(» int maxCacheEntries, | 2147 SSL_ConfigMPServerSIDCache(int maxCacheEntries, |
| 2178 » » » » PRUint32 ssl2_timeout, | 2148 PRUint32 ssl2_timeout, |
| 2179 » » » »PRUint32 ssl3_timeout, | 2149 PRUint32 ssl3_timeout, |
| 2180 » » const char * directory) | 2150 const char *directory) |
| 2181 { | 2151 { |
| 2182 PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigMPSer
verSIDCache)"); | 2152 PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigMPSer
verSIDCache)"); |
| 2183 return SECFailure; | 2153 return SECFailure; |
| 2184 } | 2154 } |
| 2185 | 2155 |
| 2186 SECStatus | 2156 SECStatus |
| 2187 SSL_InheritMPServerSIDCache(const char * envString) | 2157 SSL_InheritMPServerSIDCache(const char *envString) |
| 2188 { | 2158 { |
| 2189 PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_InheritMPSe
rverSIDCache)"); | 2159 PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_InheritMPSe
rverSIDCache)"); |
| 2190 return SECFailure; | 2160 return SECFailure; |
| 2191 } | 2161 } |
| 2192 | 2162 |
| 2193 PRBool | 2163 PRBool |
| 2194 ssl_GetWrappingKey( PRInt32 symWrapMechIndex, | 2164 ssl_GetWrappingKey(PRInt32 symWrapMechIndex, |
| 2195 SSL3KEAType exchKeyType, | 2165 SSL3KEAType exchKeyType, |
| 2196 » » SSLWrappedSymWrappingKey *wswk) | 2166 SSLWrappedSymWrappingKey *wswk) |
| 2197 { | 2167 { |
| 2198 PRBool rv = PR_FALSE; | 2168 PRBool rv = PR_FALSE; |
| 2199 PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_GetWrapping
Key)"); | 2169 PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_GetWrapping
Key)"); |
| 2200 return rv; | 2170 return rv; |
| 2201 } | 2171 } |
| 2202 | 2172 |
| 2203 /* This is a kind of test-and-set. The caller passes in the new value it wants | 2173 /* This is a kind of test-and-set. The caller passes in the new value it wants |
| 2204 * to set. This code tests the wrapped sym key entry in the shared memory. | 2174 * to set. This code tests the wrapped sym key entry in the shared memory. |
| 2205 * If it is uninitialized, this function writes the caller's value into | 2175 * If it is uninitialized, this function writes the caller's value into |
| 2206 * the disk entry, and returns false. | 2176 * the disk entry, and returns false. |
| 2207 * Otherwise, it overwrites the caller's wswk with the value obtained from | 2177 * Otherwise, it overwrites the caller's wswk with the value obtained from |
| 2208 * the disk, and returns PR_TRUE. | 2178 * the disk, and returns PR_TRUE. |
| 2209 * This is all done while holding the locks/mutexes necessary to make | 2179 * This is all done while holding the locks/mutexes necessary to make |
| 2210 * the operation atomic. | 2180 * the operation atomic. |
| 2211 */ | 2181 */ |
| 2212 PRBool | 2182 PRBool |
| 2213 ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk) | 2183 ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk) |
| 2214 { | 2184 { |
| 2215 PRBool rv = PR_FALSE; | 2185 PRBool rv = PR_FALSE; |
| 2216 PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_SetWrapping
Key)"); | 2186 PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_SetWrapping
Key)"); |
| 2217 return rv; | 2187 return rv; |
| 2218 } | 2188 } |
| 2219 | 2189 |
| 2220 PRUint32 | 2190 PRUint32 |
| 2221 SSL_GetMaxServerCacheLocks(void) | 2191 SSL_GetMaxServerCacheLocks(void) |
| 2222 { | 2192 { |
| 2223 PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_GetMaxServe
rCacheLocks)"); | 2193 PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_GetMaxServe
rCacheLocks)"); |
| 2224 return -1; | 2194 return -1; |
| 2225 } | 2195 } |
| 2226 | 2196 |
| 2227 SECStatus | 2197 SECStatus |
| 2228 SSL_SetMaxServerCacheLocks(PRUint32 maxLocks) | 2198 SSL_SetMaxServerCacheLocks(PRUint32 maxLocks) |
| 2229 { | 2199 { |
| 2230 PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_SetMaxServe
rCacheLocks)"); | 2200 PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_SetMaxServe
rCacheLocks)"); |
| 2231 return SECFailure; | 2201 return SECFailure; |
| 2232 } | 2202 } |
| 2233 | 2203 |
| 2234 #endif /* XP_UNIX || XP_WIN32 */ | 2204 #endif /* XP_UNIX || XP_WIN32 */ |
| OLD | NEW |