summaryrefslogtreecommitdiffstats
path: root/net/third_party/nss/patches/falsestart.patch
blob: a1975c6ebe37b077782090445505da03526843e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
Index: mozilla/security/nss/cmd/strsclnt/strsclnt.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/cmd/strsclnt/strsclnt.c,v
retrieving revision 1.67
diff -u -p -r1.67 strsclnt.c
--- mozilla/security/nss/cmd/strsclnt/strsclnt.c	3 Apr 2010 18:27:28 -0000	1.67
+++ mozilla/security/nss/cmd/strsclnt/strsclnt.c	29 Jul 2010 01:49:04 -0000
@@ -162,6 +162,7 @@ static PRBool disableLocking  = PR_FALSE
 static PRBool ignoreErrors    = PR_FALSE;
 static PRBool enableSessionTickets = PR_FALSE;
 static PRBool enableCompression    = PR_FALSE;
+static PRBool enableFalseStart     = PR_FALSE;
 
 PRIntervalTime maxInterval    = PR_INTERVAL_NO_TIMEOUT;
 
@@ -197,7 +198,8 @@ Usage(const char *progName)
         "       -U means enable throttling up threads\n"
 	"       -B bypasses the PKCS11 layer for SSL encryption and MACing\n"
 	"       -u enable TLS Session Ticket extension\n"
-	"       -z enable compression\n",
+	"       -z enable compression\n"
+	"       -g enable false start\n",
 	progName);
     exit(1);
 }
@@ -1244,6 +1246,12 @@ client_main(
 	    errExit("SSL_OptionSet SSL_ENABLE_DEFLATE");
     }
 
+    if (enableFalseStart) {
+	rv = SSL_OptionSet(model_sock, SSL_ENABLE_FALSE_START, PR_TRUE);
+	if (rv != SECSuccess)
+	    errExit("SSL_OptionSet SSL_ENABLE_FALSE_START");
+    }
+
     SSL_SetURL(model_sock, hostName);
 
     SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate, 
@@ -1354,7 +1362,7 @@ main(int argc, char **argv)
  
 
     optstate = PL_CreateOptState(argc, argv,
-                                 "23BC:DNP:TUW:a:c:d:f:in:op:qst:uvw:z");
+                                 "23BC:DNP:TUW:a:c:d:f:gin:op:qst:uvw:z");
     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
 	switch(optstate->option) {
 
@@ -1384,6 +1392,8 @@ main(int argc, char **argv)
 
 	case 'f': fileName = optstate->value; break;
 
+	case 'g': enableFalseStart = PR_TRUE; break;
+
 	case 'i': ignoreErrors = PR_TRUE; break;
 
         case 'n': nickName = PL_strdup(optstate->value); break;
Index: mozilla/security/nss/cmd/tstclnt/tstclnt.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/cmd/tstclnt/tstclnt.c,v
retrieving revision 1.62
diff -u -p -r1.62 tstclnt.c
--- mozilla/security/nss/cmd/tstclnt/tstclnt.c	10 Feb 2010 18:07:21 -0000	1.62
+++ mozilla/security/nss/cmd/tstclnt/tstclnt.c	29 Jul 2010 01:49:04 -0000
@@ -225,6 +225,7 @@ static void Usage(const char *progName)
     fprintf(stderr, "%-20s Renegotiate N times (resuming session if N>1).\n", "-r N");
     fprintf(stderr, "%-20s Enable the session ticket extension.\n", "-u");
     fprintf(stderr, "%-20s Enable compression.\n", "-z");
+    fprintf(stderr, "%-20s Enable false start.\n", "-g");
     fprintf(stderr, "%-20s Letter(s) chosen from the following list\n", 
                     "-c ciphers");
     fprintf(stderr, 
@@ -521,6 +522,7 @@ int main(int argc, char **argv)
     int                useExportPolicy = 0;
     int                enableSessionTickets = 0;
     int                enableCompression = 0;
+    int                enableFalseStart = 0;
     PRSocketOptionData opt;
     PRNetAddr          addr;
     PRPollDesc         pollset[2];
@@ -551,7 +553,7 @@ int main(int argc, char **argv)
     }
 
     optstate = PL_CreateOptState(argc, argv,
-                                 "23BSTW:a:c:d:fh:m:n:op:qr:suvw:xz");
+                                 "23BSTW:a:c:d:fgh:m:n:op:qr:suvw:xz");
     while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
 	switch (optstate->option) {
 	  case '?':
@@ -578,6 +580,8 @@ int main(int argc, char **argv)
 
           case 'c': cipherString = PORT_Strdup(optstate->value); break;
 
+          case 'g': enableFalseStart = 1; 		break;
+
           case 'd': certDir = PORT_Strdup(optstate->value);   break;
 
           case 'f': clientSpeaksFirst = PR_TRUE;        break;
@@ -863,7 +867,14 @@ int main(int argc, char **argv)
 	SECU_PrintError(progName, "error enabling compression");
 	return 1;
     }
-               
+
+    /* enable false start. */
+    rv = SSL_OptionSet(s, SSL_ENABLE_FALSE_START, enableFalseStart);
+    if (rv != SECSuccess) {
+	SECU_PrintError(progName, "error enabling false start");
+	return 1;
+    }
+
     SSL_SetPKCS11PinArg(s, &pwdata);
 
     SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle);
Index: mozilla/security/nss/lib/ssl/ssl.h
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl.h,v
retrieving revision 1.38
diff -u -p -r1.38 ssl.h
--- mozilla/security/nss/lib/ssl/ssl.h	17 Feb 2010 02:29:07 -0000	1.38
+++ mozilla/security/nss/lib/ssl/ssl.h	29 Jul 2010 01:49:04 -0000
@@ -128,6 +128,17 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFi
                                           /* Renegotiation  Info (RI)       */
 					  /* extension in ALL handshakes.   */
                                           /* default: off                   */
+#define SSL_ENABLE_FALSE_START         22 /* Enable SSL false start (off by */
+                                          /* default, applies only to       */
+                                          /* clients). False start is a     */
+/* mode where an SSL client will start sending application data before      */
+/* verifying the server's Finished message. This means that we could end up */
+/* sending data to an imposter. However, the data will be encrypted and     */
+/* only the true server can derive the session key. Thus, so long as the    */
+/* cipher isn't broken this is safe. Because of this, False Start will only */
+/* occur on RSA or DH ciphersuites where the cipher's key length is >= 80   */
+/* bits. The advantage of False Start is that it saves a round trip for     */
+/* client-speaks-first protocols when performing a full handshake.          */
 
 #ifdef SSL_DEPRECATED_FUNCTION 
 /* Old deprecated function names */
Index: mozilla/security/nss/lib/ssl/ssl3con.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v
retrieving revision 1.142
diff -u -p -r1.142 ssl3con.c
--- mozilla/security/nss/lib/ssl/ssl3con.c	24 Jun 2010 19:53:20 -0000	1.142
+++ mozilla/security/nss/lib/ssl/ssl3con.c	29 Jul 2010 01:49:04 -0000
@@ -5665,7 +5665,17 @@ ssl3_RestartHandshakeAfterCertReq(sslSoc
     return rv;
 }
 
-
+PRBool
+ssl3_CanFalseStart(sslSocket *ss) {
+    return ss->opt.enableFalseStart &&
+	   !ss->sec.isServer &&
+	   !ss->ssl3.hs.isResuming &&
+	   ss->ssl3.cwSpec &&
+	   ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 &&
+	   (ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_rsa ||
+	    ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_dh  ||
+	    ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh);
+}
 
 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
  * ssl3 Server Hello Done message.
@@ -5737,6 +5747,12 @@ ssl3_HandleServerHelloDone(sslSocket *ss
 	ss->ssl3.hs.ws = wait_new_session_ticket;
     else
 	ss->ssl3.hs.ws = wait_change_cipher;
+
+    /* Do the handshake callback for sslv3 here, if we can false start. */
+    if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) {
+	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
+    }
+
     return SECSuccess;
 
 loser:
@@ -8476,8 +8492,8 @@ xmit_loser:
     }
     ss->ssl3.hs.ws = idle_handshake;
 
-    /* Do the handshake callback for sslv3 here. */
-    if (ss->handshakeCallback != NULL) {
+    /* Do the handshake callback for sslv3 here, if we cannot false start. */
+    if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) {
 	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
     }
 
Index: mozilla/security/nss/lib/ssl/ssl3gthr.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3gthr.c,v
retrieving revision 1.9
diff -u -p -r1.9 ssl3gthr.c
--- mozilla/security/nss/lib/ssl/ssl3gthr.c	20 Nov 2008 07:37:25 -0000	1.9
+++ mozilla/security/nss/lib/ssl/ssl3gthr.c	29 Jul 2010 01:49:04 -0000
@@ -188,6 +188,7 @@ ssl3_GatherCompleteHandshake(sslSocket *
 {
     SSL3Ciphertext cText;
     int            rv;
+    PRBool         canFalseStart = PR_FALSE;
 
     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
     do {
@@ -207,7 +208,20 @@ ssl3_GatherCompleteHandshake(sslSocket *
 	if (rv < 0) {
 	    return ss->recvdCloseNotify ? 0 : rv;
 	}
-    } while (ss->ssl3.hs.ws != idle_handshake && ss->gs.buf.len == 0);
+
+	/* If we kicked off a false start in ssl3_HandleServerHelloDone, break
+	 * out of this loop early without finishing the handshake.
+	 */
+	if (ss->opt.enableFalseStart) {
+	    ssl_GetSSL3HandshakeLock(ss);
+	    canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher ||
+			     ss->ssl3.hs.ws == wait_new_session_ticket) &&
+		            ssl3_CanFalseStart(ss);
+	    ssl_ReleaseSSL3HandshakeLock(ss);
+	}
+    } while (ss->ssl3.hs.ws != idle_handshake &&
+             !canFalseStart &&
+             ss->gs.buf.len == 0);
 
     ss->gs.readOffset = 0;
     ss->gs.writeOffset = ss->gs.buf.len;
Index: mozilla/security/nss/lib/ssl/sslimpl.h
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslimpl.h,v
retrieving revision 1.77
diff -u -p -r1.77 sslimpl.h
--- mozilla/security/nss/lib/ssl/sslimpl.h	10 Feb 2010 00:33:50 -0000	1.77
+++ mozilla/security/nss/lib/ssl/sslimpl.h	29 Jul 2010 01:49:04 -0000
@@ -333,6 +333,7 @@ typedef struct sslOptionsStr {
     unsigned int enableDeflate          : 1;  /* 19 */
     unsigned int enableRenegotiation    : 2;  /* 20-21 */
     unsigned int requireSafeNegotiation : 1;  /* 22 */
+    unsigned int enableFalseStart       : 1;  /* 23 */
 } sslOptions;
 
 typedef enum { sslHandshakingUndetermined = 0,
@@ -1250,6 +1251,8 @@ extern void      ssl_SetAlwaysBlock(sslS
 
 extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
 
+extern PRBool    ssl3_CanFalseStart(sslSocket *ss);
+
 #define SSL_LOCK_READER(ss)		if (ss->recvLock) PZ_Lock(ss->recvLock)
 #define SSL_UNLOCK_READER(ss)		if (ss->recvLock) PZ_Unlock(ss->recvLock)
 #define SSL_LOCK_WRITER(ss)		if (ss->sendLock) PZ_Lock(ss->sendLock)
Index: mozilla/security/nss/lib/ssl/sslsecur.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslsecur.c,v
retrieving revision 1.43
diff -u -p -r1.43 sslsecur.c
--- mozilla/security/nss/lib/ssl/sslsecur.c	14 Jan 2010 22:15:25 -0000	1.43
+++ mozilla/security/nss/lib/ssl/sslsecur.c	29 Jul 2010 01:49:04 -0000
@@ -1199,8 +1199,17 @@ ssl_SecureSend(sslSocket *ss, const unsi
     	ss->writerThread = PR_GetCurrentThread();
     /* If any of these is non-zero, the initial handshake is not done. */
     if (!ss->firstHsDone) {
+	PRBool canFalseStart = PR_FALSE;
 	ssl_Get1stHandshakeLock(ss);
-	if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
+	if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
+	    (ss->ssl3.hs.ws == wait_change_cipher ||
+	     ss->ssl3.hs.ws == wait_finished ||
+	     ss->ssl3.hs.ws == wait_new_session_ticket) &&
+	    ssl3_CanFalseStart(ss)) {
+	    canFalseStart = PR_TRUE;
+	}
+	if (!canFalseStart &&
+	    (ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
 	    rv = ssl_Do1stHandshake(ss);
 	}
 	ssl_Release1stHandshakeLock(ss);
Index: mozilla/security/nss/lib/ssl/sslsock.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslsock.c,v
retrieving revision 1.67
diff -u -p -r1.67 sslsock.c
--- mozilla/security/nss/lib/ssl/sslsock.c	25 Apr 2010 23:37:38 -0000	1.67
+++ mozilla/security/nss/lib/ssl/sslsock.c	29 Jul 2010 01:49:04 -0000
@@ -183,6 +183,7 @@ static sslOptions ssl_defaults = {
     PR_FALSE,   /* enableDeflate      */
     2,          /* enableRenegotiation (default: requires extension) */
     PR_FALSE,   /* requireSafeNegotiation */
+    PR_FALSE,   /* enableFalseStart   */
 };
 
 sslSessionIDLookupFunc  ssl_sid_lookup;
@@ -728,6 +729,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh
 	ss->opt.requireSafeNegotiation = on;
 	break;
 
+      case SSL_ENABLE_FALSE_START:
+	ss->opt.enableFalseStart = on;
+	break;
+
       default:
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	rv = SECFailure;
@@ -791,6 +796,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh
                                   on = ss->opt.enableRenegotiation; break;
     case SSL_REQUIRE_SAFE_NEGOTIATION: 
                                   on = ss->opt.requireSafeNegotiation; break;
+    case SSL_ENABLE_FALSE_START:  on = ss->opt.enableFalseStart;   break;
 
     default:
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -841,6 +847,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBo
     case SSL_REQUIRE_SAFE_NEGOTIATION: 
                                   on = ssl_defaults.requireSafeNegotiation; 
 				  break;
+    case SSL_ENABLE_FALSE_START:  on = ssl_defaults.enableFalseStart;   break;
 
     default:
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -984,6 +991,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo
 	ssl_defaults.requireSafeNegotiation = on;
 	break;
 
+      case SSL_ENABLE_FALSE_START:
+	ssl_defaults.enableFalseStart = on;
+	break;
+
       default:
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	return SECFailure;
Index: mozilla/security/nss/tests/ssl/sslstress.txt
===================================================================
RCS file: /cvsroot/mozilla/security/nss/tests/ssl/sslstress.txt,v
retrieving revision 1.18
diff -u -p -r1.18 sslstress.txt
--- mozilla/security/nss/tests/ssl/sslstress.txt	3 Feb 2010 02:25:36 -0000	1.18
+++ mozilla/security/nss/tests/ssl/sslstress.txt	29 Jul 2010 01:49:04 -0000
@@ -42,9 +42,11 @@
   noECC     0      _         -c_1000_-C_A                  Stress SSL2 RC4 128 with MD5
   noECC     0      _         -c_1000_-C_c_-T               Stress SSL3 RC4 128 with MD5
   noECC     0      _         -c_1000_-C_c                  Stress TLS  RC4 128 with MD5
+  noECC     0      _         -c_1000_-C_c_-g               Stress TLS  RC4 128 with MD5 (false start)
   noECC     0      -u        -2_-c_1000_-C_c_-u            Stress TLS  RC4 128 with MD5 (session ticket)
   noECC     0      -z        -2_-c_1000_-C_c_-z            Stress TLS  RC4 128 with MD5 (compression)
   noECC     0      -u_-z     -2_-c_1000_-C_c_-u_-z         Stress TLS  RC4 128 with MD5 (session ticket, compression)
+  noECC     0      -u_-z     -2_-c_1000_-C_c_-u_-z_-g      Stress TLS  RC4 128 with MD5 (session ticket, compression, false start)
   SNI       0      -u_-a_Host-sni.Dom -2_-3_-c_1000_-C_c_-u Stress TLS RC4 128 with MD5 (session ticket, SNI)
 
 #
@@ -55,7 +57,9 @@
   noECC     0      -r_-r     -c_100_-C_c_-N_-n_TestUser    Stress TLS RC4 128 with MD5 (no reuse, client auth)
   noECC     0      -r_-r_-u  -2_-c_100_-C_c_-n_TestUser_-u Stress TLS RC4 128 with MD5 (session ticket, client auth)
   noECC     0      -r_-r_-z  -2_-c_100_-C_c_-n_TestUser_-z Stress TLS RC4 128 with MD5 (compression, client auth)
+  noECC     0      -r_-r_-z  -2_-c_100_-C_c_-n_TestUser_-z_-g Stress TLS RC4 128 with MD5 (compression, client auth, false start)
   noECC     0   -r_-r_-u_-z  -2_-c_100_-C_c_-n_TestUser_-u_-z Stress TLS RC4 128 with MD5 (session ticket, compression, client auth)
+  noECC     0   -r_-r_-u_-z  -2_-c_100_-C_c_-n_TestUser_-u_-z_-g Stress TLS RC4 128 with MD5 (session ticket, compression, client auth, false start)
   SNI       0   -r_-r_-u_-a_Host-sni.Dom -2_-3_-c_1000_-C_c_-u Stress TLS RC4 128 with MD5 (session ticket, SNI, client auth, default virt host)
   SNI       0   -r_-r_-u_-a_Host-sni.Dom_-k_Host-sni.Dom -2_-3_-c_1000_-C_c_-u_-a_Host-sni.Dom Stress TLS RC4 128 with MD5 (session ticket, SNI, client auth, change virt host)