diff options
Diffstat (limited to 'chromium/net/third_party/nss/ssl/sslnonce.c')
-rw-r--r-- | chromium/net/third_party/nss/ssl/sslnonce.c | 124 |
1 files changed, 63 insertions, 61 deletions
diff --git a/chromium/net/third_party/nss/ssl/sslnonce.c b/chromium/net/third_party/nss/ssl/sslnonce.c index a3e6e0a33f9..3e42bed34e5 100644 --- a/chromium/net/third_party/nss/ssl/sslnonce.c +++ b/chromium/net/third_party/nss/ssl/sslnonce.c @@ -21,8 +21,8 @@ PRUint32 ssl_sid_timeout = 100; PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */ -sslSessionID *cache = NULL; -PZLock * cacheLock = NULL; +static sslSessionID *cache = NULL; +static PZLock * cacheLock = NULL; /* sids can be in one of 4 states: * @@ -114,27 +114,30 @@ ssl_DestroySID(sslSessionID *sid) { int i; SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached)); - PORT_Assert((sid->references == 0)); - - if (sid->cached == in_client_cache) - return; /* it will get taken care of next time cache is traversed. */ + PORT_Assert(sid->references == 0); + PORT_Assert(sid->cached != in_client_cache); if (sid->version < SSL_LIBRARY_VERSION_3_0) { SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE); SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE); } else { - if (sid->u.ssl3.sessionTicket.ticket.data) { - SECITEM_FreeItem(&sid->u.ssl3.sessionTicket.ticket, PR_FALSE); - } - if (sid->u.ssl3.srvName.data) { - SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE); - } - if (sid->u.ssl3.signedCertTimestamps.data) { - SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE); - } - if (sid->u.ssl3.originalHandshakeHash.data) { - SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE); - } + if (sid->u.ssl3.locked.sessionTicket.ticket.data) { + SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket, + PR_FALSE); + } + if (sid->u.ssl3.srvName.data) { + SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE); + } + if (sid->u.ssl3.originalHandshakeHash.data) { + SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE); + } + if (sid->u.ssl3.signedCertTimestamps.data) { + SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE); + } + + if (sid->u.ssl3.lock) { + NSSRWLock_Destroy(sid->u.ssl3.lock); + } } if (sid->peerID != NULL) @@ -156,7 +159,7 @@ ssl_DestroySID(sslSessionID *sid) if ( sid->localCert ) { CERT_DestroyCertificate(sid->localCert); } - + PORT_ZFree(sid, sizeof(sslSessionID)); } @@ -217,9 +220,9 @@ ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID, SSL_TRC(8, ("SSL: Lookup1: sid=0x%x", sid)); - if (sid->expirationTime < now || !sid->references) { + if (sid->expirationTime < now) { /* - ** This session-id timed out, or was orphaned. + ** This session-id timed out. ** Don't even care who it belongs to, blow it out of our cache. */ SSL_TRC(7, ("SSL: lookup1, throwing sid out, age=%d refs=%d", @@ -227,11 +230,7 @@ ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID, *sidp = sid->next; /* delink it from the list. */ sid->cached = invalid_cache; /* mark not on list. */ - if (!sid->references) - ssl_DestroySID(sid); - else - ssl_FreeLockedSID(sid); /* drop ref count, free. */ - + ssl_FreeLockedSID(sid); /* drop ref count, free. */ } else if (!memcmp(&sid->addr, addr, sizeof(PRIPv6Addr)) && /* server IP addr matches */ (sid->port == port) && /* server port matches */ /* proxy (peerID) matches */ @@ -267,6 +266,9 @@ static void CacheSID(sslSessionID *sid) { PRUint32 expirationPeriod; + + PORT_Assert(sid->cached == never_cached); + SSL_TRC(8, ("SSL: Cache: sid=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x " "time=%x cached=%d", sid, sid->cached, sid->addr.pr_s6_addr32[0], @@ -274,9 +276,6 @@ CacheSID(sslSessionID *sid) sid->addr.pr_s6_addr32[3], sid->port, sid->creationTime, sid->cached)); - if (sid->cached == in_client_cache) - return; - if (!sid->urlSvrName) { /* don't cache this SID because it can never be matched */ return; @@ -293,8 +292,9 @@ CacheSID(sslSessionID *sid) sid->u.ssl2.cipherArg.data, sid->u.ssl2.cipherArg.len)); } else { if (sid->u.ssl3.sessionIDLength == 0 && - sid->u.ssl3.sessionTicket.ticket.data == NULL) + sid->u.ssl3.locked.sessionTicket.ticket.data == NULL) return; + /* Client generates the SessionID if this was a stateless resume. */ if (sid->u.ssl3.sessionIDLength == 0) { SECStatus rv; @@ -307,6 +307,11 @@ CacheSID(sslSessionID *sid) expirationPeriod = ssl3_sid_timeout; PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength)); + + sid->u.ssl3.lock = NSSRWLock_New(NSS_RWLOCK_RANK_NONE, NULL); + if (!sid->u.ssl3.lock) { + return; + } } PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0); if (!sid->creationTime) @@ -430,41 +435,38 @@ ssl_Time(void) return myTime; } -SECStatus -ssl3_SetSIDSessionTicket(sslSessionID *sid, NewSessionTicket *session_ticket) +void +ssl3_SetSIDSessionTicket(sslSessionID *sid, + /*in/out*/ NewSessionTicket *newSessionTicket) { - SECStatus rv; - - /* We need to lock the cache, as this sid might already be in the cache. */ - LOCK_CACHE; - - /* Don't modify sid if it has ever been cached. */ - if (sid->cached != never_cached) { - UNLOCK_CACHE; - return SECSuccess; - } + PORT_Assert(sid); + PORT_Assert(newSessionTicket); - /* A server might have sent us an empty ticket, which has the - * effect of clearing the previously known ticket. + /* if sid->u.ssl3.lock, we are updating an existing entry that is already + * cached or was once cached, so we need to acquire and release the write + * lock. Otherwise, this is a new session that isn't shared with anything + * yet, so no locking is needed. */ - if (sid->u.ssl3.sessionTicket.ticket.data) - SECITEM_FreeItem(&sid->u.ssl3.sessionTicket.ticket, PR_FALSE); - if (session_ticket->ticket.len > 0) { - rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.sessionTicket.ticket, - &session_ticket->ticket); - if (rv != SECSuccess) { - UNLOCK_CACHE; - return rv; + if (sid->u.ssl3.lock) { + NSSRWLock_LockWrite(sid->u.ssl3.lock); + + /* A server might have sent us an empty ticket, which has the + * effect of clearing the previously known ticket. + */ + if (sid->u.ssl3.locked.sessionTicket.ticket.data) { + SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket, + PR_FALSE); } - } else { - sid->u.ssl3.sessionTicket.ticket.data = NULL; - sid->u.ssl3.sessionTicket.ticket.len = 0; } - sid->u.ssl3.sessionTicket.received_timestamp = - session_ticket->received_timestamp; - sid->u.ssl3.sessionTicket.ticket_lifetime_hint = - session_ticket->ticket_lifetime_hint; - UNLOCK_CACHE; - return SECSuccess; + PORT_Assert(!sid->u.ssl3.locked.sessionTicket.ticket.data); + + /* Do a shallow copy, moving the ticket data. */ + sid->u.ssl3.locked.sessionTicket = *newSessionTicket; + newSessionTicket->ticket.data = NULL; + newSessionTicket->ticket.len = 0; + + if (sid->u.ssl3.lock) { + NSSRWLock_UnlockWrite(sid->u.ssl3.lock); + } } |