| Index: net/third_party/nss/ssl/sslsnce.c
|
| ===================================================================
|
| --- net/third_party/nss/ssl/sslsnce.c (revision 124359)
|
| +++ 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;
|
| }
|
|
|