| Index: net/third_party/nss/ssl/sslnonce.c
|
| ===================================================================
|
| --- net/third_party/nss/ssl/sslnonce.c (revision 242942)
|
| +++ net/third_party/nss/ssl/sslnonce.c (working copy)
|
| @@ -123,18 +123,23 @@
|
| 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) {
|
| + PR_DestroyRWLock(sid->u.ssl3.lock);
|
| + }
|
| }
|
|
|
| if (sid->peerID != NULL)
|
| @@ -156,7 +161,7 @@
|
| if ( sid->localCert ) {
|
| CERT_DestroyCertificate(sid->localCert);
|
| }
|
| -
|
| +
|
| PORT_ZFree(sid, sizeof(sslSessionID));
|
| }
|
|
|
| @@ -267,6 +272,9 @@
|
| 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 +282,6 @@
|
| 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 +298,9 @@
|
| 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 +313,11 @@
|
| expirationPeriod = ssl3_sid_timeout;
|
| PRINT_BUF(8, (0, "sessionID:",
|
| sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength));
|
| +
|
| + sid->u.ssl3.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL);
|
| + if (!sid->u.ssl3.lock) {
|
| + return;
|
| + }
|
| }
|
| PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0);
|
| if (!sid->creationTime)
|
| @@ -430,41 +441,38 @@
|
| return myTime;
|
| }
|
|
|
| -SECStatus
|
| -ssl3_SetSIDSessionTicket(sslSessionID *sid, NewSessionTicket *session_ticket)
|
| +void
|
| +ssl3_SetSIDSessionTicket(sslSessionID *sid,
|
| + /*in/out*/ NewSessionTicket *newSessionTicket)
|
| {
|
| - SECStatus rv;
|
| + PORT_Assert(sid);
|
| + PORT_Assert(newSessionTicket);
|
|
|
| - /* We need to lock the cache, as this sid might already be in the cache. */
|
| - LOCK_CACHE;
|
| + /* 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.lock) {
|
| + PR_RWLock_Wlock(sid->u.ssl3.lock);
|
|
|
| - /* Don't modify sid if it has ever been cached. */
|
| - if (sid->cached != never_cached) {
|
| - UNLOCK_CACHE;
|
| - return SECSuccess;
|
| + /* 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);
|
| + }
|
| }
|
|
|
| - /* A server might have sent us an empty ticket, which has the
|
| - * effect of clearing the previously known ticket.
|
| - */
|
| - 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;
|
| - }
|
| - } else {
|
| - sid->u.ssl3.sessionTicket.ticket.data = NULL;
|
| - sid->u.ssl3.sessionTicket.ticket.len = 0;
|
| + 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) {
|
| + PR_RWLock_Unlock(sid->u.ssl3.lock);
|
| }
|
| - 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;
|
| }
|
|
|