Bug 537356: Send SCSV in SSLv2-compatible client hellos. r=nelson.
authorwtc%google.com
Sat, 30 Jan 2010 03:48:10 +0000
changeset 9527 493636cdceea13f88a8b7f48a3db1dee1eca4c2b
parent 9526 f41abcc27d08878a1e921f6c516440f568add6ca
child 9528 9a1e1c2f5a8d48b998f415cd21ec7528458c02f7
push idunknown
push userunknown
push dateunknown
reviewersnelson
bugs537356
Bug 537356: Send SCSV in SSLv2-compatible client hellos. r=nelson.
security/nss/lib/ssl/sslcon.c
--- a/security/nss/lib/ssl/sslcon.c
+++ b/security/nss/lib/ssl/sslcon.c
@@ -207,20 +207,22 @@ ssl2_ConstructCipherSpecs(sslSocket *ss)
 
     /* ask SSL3 how many cipher suites it has. */
     rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count);
     if (rv < 0) 
 	return rv;
     count += ssl3_count;
 
     /* Allocate memory to hold cipher specs */
-    if (count > 0)
+    if (count > 0) {
+	++count; /* add one for SCSV */
 	cs = (PRUint8*) PORT_Alloc(count * 3);
-    else
+    } else {
 	PORT_SetError(SSL_ERROR_SSL_DISABLED);
+    }
     if (cs == NULL)
     	return SECFailure;
 
     if (ss->cipherSpecs != NULL) {
 	PORT_Free(ss->cipherSpecs);
     }
     ss->cipherSpecs     = cs;
     ss->sizeCipherSpecs = count * 3;
@@ -234,16 +236,22 @@ ssl2_ConstructCipherSpecs(sslSocket *ss)
 	if (ok) {
 	    cs[0] = hs[0];
 	    cs[1] = hs[1];
 	    cs[2] = hs[2];
 	    cs += 3;
 	}
     }
 
+    /* add SCSV */
+    cs[0] = 0x00;
+    cs[1] = 0x00;
+    cs[2] = 0xff;
+    cs += 3;
+
     /* now have SSL3 add its suites onto the end */
     rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count);
     
     /* adjust for any difference between first pass and second pass */
     ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3;
 
     return rv;
 }
@@ -3002,16 +3010,17 @@ ssl2_BeginClientHandshake(sslSocket *ss)
     sslSessionID      *sid;
     PRUint8           *msg;
     PRUint8           *cp;
     PRUint8           *localCipherSpecs = NULL;
     unsigned int      localCipherSize;
     unsigned int      i;
     int               sendLen, sidLen = 0;
     SECStatus         rv;
+    TLSExtensionData  *xtnData;
 
     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
 
     ss->sec.isServer     = 0;
     ss->sec.sendSequence = 0;
     ss->sec.rcvSequence  = 0;
     ssl_ChooseSessionIDProcs(&ss->sec);
 
@@ -3202,16 +3211,20 @@ ssl2_BeginClientHandshake(sslSocket *ss)
 	goto loser;
     }
 
     rv = ssl3_StartHandshakeHash(ss, msg, sendLen);
     if (rv < 0) {
 	goto loser;
     }
 
+    /* Since we sent the SCSV, pretend we sent empty RI extension. */
+    xtnData = &ss->xtnData;
+    xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn;
+
     /* Setup to receive servers hello message */
     ssl_GetRecvBufLock(ss);
     ss->gs.recordLen = 0;
     ssl_ReleaseRecvBufLock(ss);
 
     ss->handshake     = ssl_GatherRecord1stHandshake;
     ss->nextHandshake = ssl2_HandleServerHelloMessage;
     return SECSuccess;