Index: net/third_party/nss/ssl/sslsnce.c |
=================================================================== |
--- net/third_party/nss/ssl/sslsnce.c (revision 124804) |
+++ net/third_party/nss/ssl/sslsnce.c (working copy) |
@@ -36,7 +36,7 @@ |
* the terms of any one of the MPL, the GPL or the LGPL. |
* |
* ***** END LICENSE BLOCK ***** */ |
-/* $Id: sslsnce.c,v 1.54 2010/07/05 19:31:56 alexei.volkov.bugs%sun.com Exp $ */ |
+/* $Id: sslsnce.c,v 1.59 2011/10/22 16:45:40 emaldona%redhat.com Exp $ */ |
/* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server |
* cache sids! |
@@ -1026,15 +1026,16 @@ |
int locks_initialized = cache->numSIDCacheLocksInitialized; |
if (cache->cacheMem) { |
- /* If everInherited is true, this shared cache was (and may still |
- ** be) in use by multiple processes. We do not wish to destroy |
- ** the mutexes while they are still in use. |
- */ |
- if (cache->sharedCache && |
- PR_FALSE == cache->sharedCache->everInherited) { |
+ if (cache->sharedCache) { |
sidCacheLock *pLock = cache->sidCacheLocks; |
for (; locks_initialized > 0; --locks_initialized, ++pLock ) { |
- sslMutex_Destroy(&pLock->mutex); |
+ /* If everInherited is true, this shared cache was (and may |
+ ** still be) in use by multiple processes. We do not wish to |
+ ** destroy the mutexes while they are still in use, but we do |
+ ** want to free mutex resources associated with this process. |
+ */ |
+ sslMutex_Destroy(&pLock->mutex, |
+ cache->sharedCache->everInherited); |
} |
} |
if (cache->shared) { |
@@ -1331,6 +1332,11 @@ |
PORT_Assert(sizeof(certCacheEntry) == 4096); |
PORT_Assert(sizeof(srvNameCacheEntry) == 1072); |
+ rv = ssl_Init(); |
+ if (rv != SECSuccess) { |
+ return rv; |
+ } |
+ |
myPid = SSL_GETPID(); |
if (!directory) { |
directory = DEFAULT_CACHE_DIRECTORY; |
@@ -1511,7 +1517,12 @@ |
int locks_initialized = 0; |
int locks_to_initialize = 0; |
#endif |
+ SECStatus status = ssl_Init(); |
+ if (status != SECSuccess) { |
+ return status; |
+ } |
+ |
myPid = SSL_GETPID(); |
/* If this child was created by fork(), and not by exec() on unix, |
@@ -1863,17 +1874,25 @@ |
} |
static PRBool |
-GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg, |
- unsigned char *keyName, PK11SymKey **aesKey, |
- PK11SymKey **macKey) |
+GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey, |
+ PK11SymKey **macKey) |
{ |
PK11SlotInfo *slot; |
CK_MECHANISM_TYPE mechanismArray[2]; |
PK11SymKey *aesKeyTmp = NULL; |
PK11SymKey *macKeyTmp = NULL; |
cacheDesc *cache = &globalCache; |
+ uint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN]; |
+ uint8 *ticketKeyNameSuffix; |
- if (PK11_GenerateRandom(cache->ticketKeyNameSuffix, |
+ if (!cache->cacheMem) { |
+ /* cache is not initalized. Use stack buffer */ |
+ ticketKeyNameSuffix = ticketKeyNameSuffixLocal; |
+ } else { |
+ ticketKeyNameSuffix = cache->ticketKeyNameSuffix; |
+ } |
+ |
+ if (PK11_GenerateRandom(ticketKeyNameSuffix, |
SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess) { |
SSL_DBG(("%d: SSL[%s]: Unable to generate random key name bytes.", |
SSL_GETPID(), "unknown")); |
@@ -1885,9 +1904,10 @@ |
slot = PK11_GetBestSlotMultiple(mechanismArray, 2, pwArg); |
if (slot) { |
- aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL, 32, pwArg); |
- macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL, SHA256_LENGTH, |
- pwArg); |
+ aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL, |
+ AES_256_KEY_LENGTH, pwArg); |
+ macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL, |
+ SHA256_LENGTH, pwArg); |
PK11_FreeSlot(slot); |
} |
@@ -1896,15 +1916,39 @@ |
SSL_GETPID(), "unknown")); |
goto loser; |
} |
+ PORT_Memcpy(keyName, ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN); |
+ *aesKey = aesKeyTmp; |
+ *macKey = macKeyTmp; |
+ return PR_TRUE; |
- /* Export the keys to the shared cache in wrapped form. */ |
- if (!WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey)) |
- goto loser; |
- if (!WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey)) |
- goto loser; |
+loser: |
+ if (aesKeyTmp) |
+ PK11_FreeSymKey(aesKeyTmp); |
+ if (macKeyTmp) |
+ PK11_FreeSymKey(macKeyTmp); |
+ return PR_FALSE; |
+} |
- PORT_Memcpy(keyName, cache->ticketKeyNameSuffix, |
- SESS_TICKET_KEY_VAR_NAME_LEN); |
+static PRBool |
+GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg, |
+ unsigned char *keyName, PK11SymKey **aesKey, |
+ PK11SymKey **macKey) |
+{ |
+ PK11SymKey *aesKeyTmp = NULL; |
+ PK11SymKey *macKeyTmp = NULL; |
+ cacheDesc *cache = &globalCache; |
+ |
+ if (!GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp)) { |
+ goto loser; |
+ } |
+ |
+ if (cache->cacheMem) { |
+ /* Export the keys to the shared cache in wrapped form. */ |
+ if (!WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey)) |
+ goto loser; |
+ if (!WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey)) |
+ goto loser; |
+ } |
*aesKey = aesKeyTmp; |
*macKey = macKeyTmp; |
return PR_TRUE; |
@@ -1971,6 +2015,12 @@ |
PRBool keysGenerated = PR_FALSE; |
cacheDesc *cache = &globalCache; |
+ if (!cache->cacheMem) { |
+ /* cache is uninitialized. Generate keys and return them |
+ * without caching. */ |
+ return GenerateTicketKeys(pwArg, keyName, aesKey, macKey); |
+ } |
+ |
now = LockSidCacheLock(cache->keyCacheLock, now); |
if (!now) |
return rv; |
@@ -2000,33 +2050,58 @@ |
PRBool rv = PR_FALSE; |
PRUint32 now = 0; |
cacheDesc *cache = &globalCache; |
+ uint8 ticketMacKey[AES_256_KEY_LENGTH], ticketEncKey[SHA256_LENGTH]; |
+ uint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN]; |
+ uint8 *ticketMacKeyPtr, *ticketEncKeyPtr, *ticketKeyNameSuffix; |
+ PRBool cacheIsEnabled = PR_TRUE; |
- /* Grab lock. */ |
- now = LockSidCacheLock(cache->keyCacheLock, now); |
- if (!now) |
- return rv; |
+ if (!cache->cacheMem) { /* cache is uninitialized */ |
+ cacheIsEnabled = PR_FALSE; |
+ ticketKeyNameSuffix = ticketKeyNameSuffixLocal; |
+ ticketEncKeyPtr = ticketEncKey; |
+ ticketMacKeyPtr = ticketMacKey; |
+ } else { |
+ /* these values have constant memory locations in the cache. |
+ * Ok to reference them without holding the lock. */ |
+ ticketKeyNameSuffix = cache->ticketKeyNameSuffix; |
+ ticketEncKeyPtr = cache->ticketEncKey->bytes; |
+ ticketMacKeyPtr = cache->ticketMacKey->bytes; |
+ } |
- if (!*(cache->ticketKeysValid)) { |
- if (PK11_GenerateRandom(cache->ticketKeyNameSuffix, |
+ if (cacheIsEnabled) { |
+ /* Grab lock if initialized. */ |
+ now = LockSidCacheLock(cache->keyCacheLock, now); |
+ if (!now) |
+ return rv; |
+ } |
+ /* Going to regenerate keys on every call if cache was not |
+ * initialized. */ |
+ if (!cacheIsEnabled || !*(cache->ticketKeysValid)) { |
+ if (PK11_GenerateRandom(ticketKeyNameSuffix, |
SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess) |
goto loser; |
- if (PK11_GenerateRandom(cache->ticketEncKey->bytes, 32) != SECSuccess) |
+ if (PK11_GenerateRandom(ticketEncKeyPtr, |
+ AES_256_KEY_LENGTH) != SECSuccess) |
goto loser; |
- if (PK11_GenerateRandom(cache->ticketMacKey->bytes, |
- SHA256_LENGTH) != SECSuccess) |
+ if (PK11_GenerateRandom(ticketMacKeyPtr, |
+ SHA256_LENGTH) != SECSuccess) |
goto loser; |
- *(cache->ticketKeysValid) = 1; |
+ if (cacheIsEnabled) { |
+ *(cache->ticketKeysValid) = 1; |
+ } |
} |
rv = PR_TRUE; |
loser: |
- UnlockSidCacheLock(cache->keyCacheLock); |
+ if (cacheIsEnabled) { |
+ UnlockSidCacheLock(cache->keyCacheLock); |
+ } |
if (rv) { |
- PORT_Memcpy(keyName, cache->ticketKeyNameSuffix, |
- SESS_TICKET_KEY_VAR_NAME_LEN); |
- PORT_Memcpy(encKey, cache->ticketEncKey->bytes, 32); |
- PORT_Memcpy(macKey, cache->ticketMacKey->bytes, SHA256_LENGTH); |
+ PORT_Memcpy(keyName, ticketKeyNameSuffix, |
+ SESS_TICKET_KEY_VAR_NAME_LEN); |
+ PORT_Memcpy(encKey, ticketEncKeyPtr, AES_256_KEY_LENGTH); |
+ PORT_Memcpy(macKey, ticketMacKeyPtr, SHA256_LENGTH); |
} |
return rv; |
} |