Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: net/third_party/nss/patches/falsestart.patch

Issue 518065: Disable Nagle on Linux and TLS cut through support (Closed)
Patch Set: ... Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 diff --git a/mozilla/security/nss/cmd/strsclnt/strsclnt.c b/mozilla/security/nss /cmd/strsclnt/strsclnt.c
wtc 2010/02/20 00:39:51 Remove the NPN changes from this patch.
2 index c266644..1f71434 100644
3 --- a/mozilla/security/nss/cmd/strsclnt/strsclnt.c
4 +++ b/mozilla/security/nss/cmd/strsclnt/strsclnt.c
5 @@ -162,6 +162,7 @@ static PRBool disableLocking = PR_FALSE;
6 static PRBool ignoreErrors = PR_FALSE;
7 static PRBool enableSessionTickets = PR_FALSE;
8 static PRBool enableCompression = PR_FALSE;
9 +static PRBool enableFalseStart = PR_FALSE;
10
11 PRIntervalTime maxInterval = PR_INTERVAL_NO_TIMEOUT;
12
13 @@ -197,7 +198,8 @@ Usage(const char *progName)
14 " -U means enable throttling up threads\n"
15 " -B bypasses the PKCS11 layer for SSL encryption and MACing\n"
16 " -u enable TLS Session Ticket extension\n"
17 - " -z enable compression\n",
18 + " -z enable compression\n"
19 + " -g enable false start\n",
20 progName);
21 exit(1);
22 }
23 @@ -1244,6 +1246,12 @@ client_main(
24 errExit("SSL_OptionSet SSL_ENABLE_DEFLATE");
25 }
26
27 + if (enableFalseStart) {
28 + rv = SSL_OptionSet(model_sock, SSL_ENABLE_FALSE_START, PR_TRUE);
29 + if (rv != SECSuccess)
30 + errExit("SSL_OptionSet SSL_ENABLE_FALSE_START");
31 + }
32 +
33 SSL_SetURL(model_sock, hostName);
34
35 SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,
36 @@ -1354,7 +1362,7 @@ main(int argc, char **argv)
37
38
39 optstate = PL_CreateOptState(argc, argv,
40 - "23BC:DNP:TUW:a:c:d:f:in:op:qst:uvw:z");
41 + "23BC:DNP:TUW:a:c:d:f:gin:op:qst:uvw:z");
42 while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
43 switch(optstate->option) {
44
45 @@ -1384,6 +1392,8 @@ main(int argc, char **argv)
46
47 case 'f': fileName = optstate->value; break;
48
49 + case 'g': enableFalseStart = PR_TRUE; break;
50 +
51 case 'i': ignoreErrors = PR_TRUE; break;
52
53 case 'n': nickName = PL_strdup(optstate->value); break;
54 diff --git a/mozilla/security/nss/cmd/tstclnt/tstclnt.c b/mozilla/security/nss/c md/tstclnt/tstclnt.c
55 index c15a0ad..d209a33 100644
56 --- a/mozilla/security/nss/cmd/tstclnt/tstclnt.c
57 +++ b/mozilla/security/nss/cmd/tstclnt/tstclnt.c
58 @@ -225,6 +225,7 @@ static void Usage(const char *progName)
59 fprintf(stderr, "%-20s Renegotiate N times (resuming session if N>1).\n", " -r N");
60 fprintf(stderr, "%-20s Enable the session ticket extension.\n", "-u");
61 fprintf(stderr, "%-20s Enable compression.\n", "-z");
62 + fprintf(stderr, "%-20s Enable false start.\n", "-g");
63 fprintf(stderr, "%-20s Letter(s) chosen from the following list\n",
64 "-c ciphers");
65 fprintf(stderr,
66 @@ -521,6 +522,7 @@ int main(int argc, char **argv)
67 int useExportPolicy = 0;
68 int enableSessionTickets = 0;
69 int enableCompression = 0;
70 + int enableFalseStart = 0;
71 PRSocketOptionData opt;
72 PRNetAddr addr;
73 PRPollDesc pollset[2];
74 @@ -551,7 +553,7 @@ int main(int argc, char **argv)
75 }
76
77 optstate = PL_CreateOptState(argc, argv,
78 - "23BSTW:a:c:d:fh:m:n:op:qr:suvw:xz");
79 + "23BSTW:a:c:d:fgh:m:n:op:qr:suvw:xz");
80 while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
81 switch (optstate->option) {
82 case '?':
83 @@ -578,6 +580,8 @@ int main(int argc, char **argv)
84
85 case 'c': cipherString = PORT_Strdup(optstate->value); break;
86
87 + case 'g': enableFalseStart = 1; break;
88 +
89 case 'd': certDir = PORT_Strdup(optstate->value); break;
90
91 case 'f': clientSpeaksFirst = PR_TRUE; break;
92 @@ -863,7 +867,20 @@ int main(int argc, char **argv)
93 SECU_PrintError(progName, "error enabling compression");
94 return 1;
95 }
96 -
97 +
98 + rv = SSL_SetNextProtoNego(s, "\004flip\004http1.1", 10);
99 + if (rv != SECSuccess) {
100 + SECU_PrintError(progName, "error enabling next protocol negotiation");
101 + return 1;
102 + }
103 +
104 + /* enable false start. */
105 + rv = SSL_OptionSet(s, SSL_ENABLE_FALSE_START, enableFalseStart);
106 + if (rv != SECSuccess) {
107 + SECU_PrintError(progName, "error enabling false start");
108 + return 1;
109 + }
110 +
111 SSL_SetPKCS11PinArg(s, &pwdata);
112
113 SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle);
114 diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl /ssl.def
115 index d3f455c..a1f4b51 100644
116 --- a/mozilla/security/nss/lib/ssl/ssl.def
117 +++ b/mozilla/security/nss/lib/ssl/ssl.def
118 @@ -152,3 +152,10 @@ SSL_SNISocketConfigHook;
119 ;+ local:
120 ;+*;
121 ;+};
122 +;+NSS_CHROMIUM {
123 +;+ global:
124 +SSL_GetNextProto;
125 +SSL_SetNextProtoNego;
126 +;+ local:
127 +;+*;
128 +;+};
129 diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/s sl.h
130 index e285ab4..60fc9b5 100644
131 --- a/mozilla/security/nss/lib/ssl/ssl.h
132 +++ b/mozilla/security/nss/lib/ssl/ssl.h
133 @@ -128,6 +128,17 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFi leDesc *fd);
134 /* Renegotiation Info (RI) */
135 /* extension in ALL handshakes. */
136 /* default: off */
137 +#define SSL_ENABLE_FALSE_START 22 /* Enable SSL false start (off by */
138 + /* default, applies only to */
139 + /* clients). False start is a */
140 +/* mode where an SSL client will start sending application data before */
141 +/* verifing the server's Finished message. This means that we could end up */
142 +/* sending data to an imposter. However, the data will be encrypted and */
143 +/* only the true server can decrypt the session key. Thus, so long as the */
144 +/* cipher isn't broken this is safe. Because of this, False Start will only */
145 +/* occur on RSA ciphersuites where the cipher's key length is >= 80 bits. */
146 +/* The advantage of False Start is that it saves a round trip for */
147 +/* client-speaks-first protocols when performing a full handshake. */
148
149 #ifdef SSL_DEPRECATED_FUNCTION
150 /* Old deprecated function names */
151 @@ -142,6 +153,18 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, P RBool on);
152 SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on);
153 SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHa ndle);
154
155 +SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd,
156 + const unsigned char *data,
157 + unsigned short length);
158 +SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd,
159 + int *state,
160 + unsigned char *buf,
161 + unsigned *length,
162 + unsigned buf_len);
163 +#define SSL_NEXT_PROTO_NO_SUPPORT 0 /* No peer support */
164 +#define SSL_NEXT_PROTO_NEGOTIATED 1 /* Mutual agreement */
165 +#define SSL_NEXT_PROTO_NO_OVERLAP 2 /* No protocol overlap found */
166 +
167 /*
168 ** Control ciphers that SSL uses. If on is non-zero then the named cipher
169 ** is enabled, otherwise it is disabled.
170 diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/s sl/ssl3con.c
171 index 6b37c4f..dd1ac73 100644
172 --- a/mozilla/security/nss/lib/ssl/ssl3con.c
173 +++ b/mozilla/security/nss/lib/ssl/ssl3con.c
174 @@ -81,6 +81,7 @@ static SECStatus ssl3_InitState( sslSocket *ss);
175 static SECStatus ssl3_SendCertificate( sslSocket *ss);
176 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss);
177 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
178 +static SECStatus ssl3_SendNextProto( sslSocket *ss);
179 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags);
180 static SECStatus ssl3_SendServerHello( sslSocket *ss);
181 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss);
182 @@ -5656,7 +5657,15 @@ ssl3_RestartHandshakeAfterCertReq(sslSocket * ss,
183 return rv;
184 }
185
186 -
187 +PRBool
188 +ssl3_CanFalseStart(sslSocket *ss) {
189 + return ss->opt.enableFalseStart &&
190 + !ss->sec.isServer &&
191 + !ss->ssl3.hs.isResuming &&
192 + ss->ssl3.cwSpec &&
193 + ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 &&
194 + ss->ssl3.hs.kea_def->exchKeyType == kt_rsa;
195 +}
196
197 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
198 * ssl3 Server Hello Done message.
199 @@ -5717,6 +5726,12 @@ ssl3_HandleServerHelloDone(sslSocket *ss)
200 if (rv != SECSuccess) {
201 goto loser; /* err code was set. */
202 }
203 +
204 + rv = ssl3_SendNextProto(ss);
205 + if (rv != SECSuccess) {
206 + goto loser; /* err code was set. */
207 + }
208 +
209 rv = ssl3_SendFinished(ss, 0);
210 if (rv != SECSuccess) {
211 goto loser; /* err code was set. */
212 @@ -5728,6 +5743,12 @@ ssl3_HandleServerHelloDone(sslSocket *ss)
213 ss->ssl3.hs.ws = wait_new_session_ticket;
214 else
215 ss->ssl3.hs.ws = wait_change_cipher;
216 +
217 + /* Do the handshake callback for sslv3 here. */
218 + if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) {
219 + (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
220 + }
221 +
222 return SECSuccess;
223
224 loser:
225 @@ -8138,6 +8159,40 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
226 }
227
228 /* called from ssl3_HandleServerHelloDone
229 + */
230 +static SECStatus
231 +ssl3_SendNextProto(sslSocket *ss)
232 +{
233 + SECStatus rv;
234 + int padding_len;
235 + static const unsigned char padding[32] = {0};
236 +
237 + if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NO_SUPPORT)
238 + return SECSuccess;
239 +
240 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
241 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
242 +
243 + padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32);
244 +
245 + rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len +
246 + 2 + padding_len);
247 + if (rv != SECSuccess) {
248 + return rv; /* error code set by AppendHandshakeHeader */
249 + }
250 + rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data,
251 + ss->ssl3.nextProto.len, 1);
252 + if (rv != SECSuccess) {
253 + return rv; /* error code set by AppendHandshake */
254 + }
255 + rv = ssl3_AppendHandshakeVariable(ss, padding, padding_len, 1);
256 + if (rv != SECSuccess) {
257 + return rv; /* error code set by AppendHandshake */
258 + }
259 + return rv;
260 +}
261 +
262 +/* called from ssl3_HandleServerHelloDone
263 * ssl3_HandleClientHello
264 * ssl3_HandleFinished
265 */
266 @@ -8468,7 +8523,7 @@ xmit_loser:
267 ss->ssl3.hs.ws = idle_handshake;
268
269 /* Do the handshake callback for sslv3 here. */
270 - if (ss->handshakeCallback != NULL) {
271 + if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) {
272 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
273 }
274
275 @@ -9457,6 +9512,11 @@ ssl3_DestroySSL3Info(sslSocket *ss)
276 ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/);
277
278 ss->ssl3.initialized = PR_FALSE;
279 +
280 + if (ss->ssl3.nextProto.data) {
281 + PORT_Free(ss->ssl3.nextProto.data);
282 + ss->ssl3.nextProto.data = NULL;
283 + }
284 }
285
286 /* End of ssl3con.c */
287 diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/s sl/ssl3ext.c
288 index fd0d9b9..ead0cfd 100644
289 --- a/mozilla/security/nss/lib/ssl/ssl3ext.c
290 +++ b/mozilla/security/nss/lib/ssl/ssl3ext.c
291 @@ -235,6 +235,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
292 #endif
293 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
294 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
295 + { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
296 { -1, NULL }
297 };
298
299 @@ -245,6 +246,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTL S[] = {
300 /* TODO: add a handler for ssl_ec_point_formats_xtn */
301 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
302 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
303 + { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
304 { -1, NULL }
305 };
306
307 @@ -267,7 +269,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTEN SIONS] = {
308 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
309 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
310 #endif
311 - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }
312 + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
313 + { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }
314 /* any extra entries will appear as { 0, NULL } */
315 };
316
317 @@ -532,6 +535,123 @@ ssl3_SendSessionTicketXtn(
318 return -1;
319 }
320
321 +/* handle an incoming Next Protocol Negotiation extension. */
322 +SECStatus
323 +ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *da ta)
324 +{
325 + if (data->len != 0) {
326 + /* Clients MUST send an empty NPN extension, if any. */
327 + return SECFailure;
328 + }
329 +
330 + ss->ssl3.hs.nextProtoNego = PR_TRUE;
331 + return SECSuccess;
332 +}
333 +
334 +/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: non e
335 + * of the length may be 0 and the sum of the lengths must equal the length of
336 + * the block. */
337 +SECStatus
338 +ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length)
339 +{
340 + unsigned int offset = 0;
341 +
342 + while (offset < length) {
343 + if (data[offset] == 0) {
344 + return SECFailure;
345 + }
346 + offset += (unsigned int)data[offset] + 1;
347 + }
348 +
349 + if (offset > length)
350 + return SECFailure;
351 +
352 + return SECSuccess;
353 +}
354 +
355 +SECStatus
356 +ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
357 + SECItem *data)
358 +{
359 + unsigned int i, j;
360 + SECStatus rv;
361 + unsigned char *result;
362 +
363 + if (data->len == 0) {
364 + /* The server supports the extension, but doesn't have any
365 + * protocols configured. In this case we request our favoured
366 + * protocol. */
367 + goto pick_first;
368 + }
369 +
370 + rv = ssl3_ValidateNextProtoNego(data->data, data->len);
371 + if (rv != SECSuccess)
372 + return rv;
373 +
374 + /* For each protocol in server preference order, see if we support it. */
375 + for (i = 0; i < data->len; ) {
376 + for (j = 0; j < ss->opt.nextProtoNego.len; ) {
377 + if (data->data[i] == ss->opt.nextProtoNego.data[j] &&
378 + memcmp(&data->data[i+1], &ss->opt.nextProtoNego.data[j+1],
379 + data->data[i]) == 0) {
380 + /* We found a match */
381 + ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
382 + result = &data->data[i];
383 + goto found;
384 + }
385 + j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1;
386 + }
387 +
388 + i += (unsigned int)data->data[i] + 1;
389 + }
390 +
391 + pick_first:
392 + ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
393 + result = ss->opt.nextProtoNego.data;
394 +
395 + found:
396 + if (ss->ssl3.nextProto.data)
397 + PORT_Free(ss->ssl3.nextProto.data);
398 + ss->ssl3.nextProto.data = PORT_Alloc(result[0]);
399 + PORT_Memcpy(ss->ssl3.nextProto.data, result + 1, result[0]);
400 + ss->ssl3.nextProto.len = result[0];
401 + return SECSuccess;
402 +}
403 +
404 +PRInt32
405 +ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss,
406 + PRBool append,
407 + PRUint32 maxBytes)
408 +{
409 + PRInt32 extension_length;
410 +
411 + /* Renegotiations do not send this extension. */
412 + if (ss->opt.nextProtoNego.len == 0 || ss->firstHsDone) {
413 + return 0;
414 + }
415 +
416 + extension_length = 4;
417 +
418 + if (append && maxBytes >= extension_length) {
419 + SECStatus rv;
420 + rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2);
421 + if (rv != SECSuccess)
422 + goto loser;
423 + rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
424 + if (rv != SECSuccess)
425 + goto loser;
426 + ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
427 + ssl_next_proto_neg_xtn;
428 + } else if (maxBytes < extension_length) {
429 + return 0;
430 + }
431 +
432 + return extension_length;
433 +
434 + loser:
435 + return -1;
436 +}
437 +
438 /*
439 * NewSessionTicket
440 * Called from ssl3_HandleFinished
441 diff --git a/mozilla/security/nss/lib/ssl/ssl3gthr.c b/mozilla/security/nss/lib/ ssl/ssl3gthr.c
442 index bdd2958..28fe154 100644
443 --- a/mozilla/security/nss/lib/ssl/ssl3gthr.c
444 +++ b/mozilla/security/nss/lib/ssl/ssl3gthr.c
445 @@ -188,6 +188,7 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
446 {
447 SSL3Ciphertext cText;
448 int rv;
449 + PRBool canFalseStart = PR_FALSE;
450
451 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
452 do {
453 @@ -207,7 +208,17 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
454 if (rv < 0) {
455 return ss->recvdCloseNotify ? 0 : rv;
456 }
457 - } while (ss->ssl3.hs.ws != idle_handshake && ss->gs.buf.len == 0);
458 +
459 + if (ss->opt.enableFalseStart) {
460 + ssl_GetSSL3HandshakeLock(ss);
461 + canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher ||
462 + ss->ssl3.hs.ws == wait_new_session_ticket) &&
463 + ssl3_CanFalseStart(ss);
464 + ssl_ReleaseSSL3HandshakeLock(ss);
465 + }
466 + } while (ss->ssl3.hs.ws != idle_handshake &&
467 + !canFalseStart &&
468 + ss->gs.buf.len == 0);
469
470 ss->gs.readOffset = 0;
471 ss->gs.writeOffset = ss->gs.buf.len;
472 diff --git a/mozilla/security/nss/lib/ssl/ssl3prot.h b/mozilla/security/nss/lib/ ssl/ssl3prot.h
473 index 0fc1675..c82c891 100644
474 --- a/mozilla/security/nss/lib/ssl/ssl3prot.h
475 +++ b/mozilla/security/nss/lib/ssl/ssl3prot.h
476 @@ -157,7 +157,8 @@ typedef enum {
477 server_hello_done = 14,
478 certificate_verify = 15,
479 client_key_exchange = 16,
480 - finished = 20
481 + finished = 20,
482 + next_proto = 67
483 } SSL3HandshakeType;
484
485 typedef struct {
486 diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/s sl/sslimpl.h
487 index 7581b98..a800d56 100644
488 --- a/mozilla/security/nss/lib/ssl/sslimpl.h
489 +++ b/mozilla/security/nss/lib/ssl/sslimpl.h
490 @@ -313,6 +313,11 @@ typedef struct {
491 #endif /* NSS_ENABLE_ECC */
492
493 typedef struct sslOptionsStr {
494 + /* For clients, this is a validated list of protocols in preference order
495 + * and wire format. For servers, this is the list of support protocols,
496 + * also in wire format. */
497 + SECItem nextProtoNego;
498 +
499 unsigned int useSecurity : 1; /* 1 */
500 unsigned int useSocks : 1; /* 2 */
501 unsigned int requestCertificate : 1; /* 3 */
502 @@ -333,6 +338,7 @@ typedef struct sslOptionsStr {
503 unsigned int enableDeflate : 1; /* 19 */
504 unsigned int enableRenegotiation : 2; /* 20-21 */
505 unsigned int requireSafeNegotiation : 1; /* 22 */
506 + unsigned int enableFalseStart : 1; /* 23 */
507 } sslOptions;
508
509 typedef enum { sslHandshakingUndetermined = 0,
510 @@ -785,6 +791,7 @@ const ssl3CipherSuiteDef *suite_def;
511 #ifdef NSS_ENABLE_ECC
512 PRUint32 negotiatedECCurves; /* bit mask */
513 #endif /* NSS_ENABLE_ECC */
514 + PRBool nextProtoNego;/* Our peer has sent this extension */
515 } SSL3HandshakeState;
516
517
518 @@ -826,6 +833,16 @@ struct ssl3StateStr {
519 PRBool initialized;
520 SSL3HandshakeState hs;
521 ssl3CipherSpec specs[2]; /* one is current, one is pending. */
522 +
523 + /* In a client: if the server supports Next Protocol Negotiation, then
524 + * this is the protocol that was requested.
525 + * In a server: this is the protocol that the client requested via Next
526 + * Protocol Negotiation.
527 + *
528 + * In either case, if the data pointer is non-NULL, then it is malloced
529 + * data. */
530 + SECItem nextProto;
531 + int nextProtoState; /* See SSL_NEXT_PROTO_* defines */
532 };
533
534 typedef struct {
535 @@ -1250,6 +1267,8 @@ extern void ssl_SetAlwaysBlock(sslSocket *ss);
536
537 extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
538
539 +extern PRBool ssl3_CanFalseStart(sslSocket *ss);
540 +
541 #define SSL_LOCK_READER(ss) if (ss->recvLock) PZ_Lock(ss->recvLock)
542 #define SSL_UNLOCK_READER(ss) if (ss->recvLock) PZ_Unlock(ss->recvLock )
543 #define SSL_LOCK_WRITER(ss) if (ss->sendLock) PZ_Lock(ss->sendLock)
544 @@ -1491,8 +1510,12 @@ extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslS ocket * ss,
545 PRUint16 ex_type, SECItem *data);
546 extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss,
547 PRUint16 ex_type, SECItem *data);
548 +extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
549 + PRUint16 ex_type, SECItem *data);
550 extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss,
551 PRUint16 ex_type, SECItem *data);
552 +extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
553 + PRUint16 ex_type, SECItem *data);
554
555 /* ClientHello and ServerHello extension senders.
556 * Note that not all extension senders are exposed here; only those that
557 @@ -1523,6 +1546,10 @@ extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss,
558 extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss,
559 PRBool append, PRUint32 maxBytes);
560 #endif
561 +extern PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
562 + PRUint32 maxBytes);
563 +extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data,
564 + unsigned short length);
565
566 /* call the registered extension handlers. */
567 extern SECStatus ssl3_HandleHelloExtensions(sslSocket *ss,
568 diff --git a/mozilla/security/nss/lib/ssl/sslsecur.c b/mozilla/security/nss/lib/ ssl/sslsecur.c
569 index 8f79135..33ad2c3 100644
570 --- a/mozilla/security/nss/lib/ssl/sslsecur.c
571 +++ b/mozilla/security/nss/lib/ssl/sslsecur.c
572 @@ -148,6 +148,12 @@ ssl_Do1stHandshake(sslSocket *ss)
573 ss->gs.readOffset = 0;
574 break;
575 }
576 + if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
577 + ssl3_CanFalseStart(ss) &&
578 + (ss->ssl3.hs.ws == wait_change_cipher ||
579 + ss->ssl3.hs.ws == wait_new_session_ticket)) {
580 + break;
581 + }
582 rv = (*ss->handshake)(ss);
583 ++loopCount;
584 /* This code must continue to loop on SECWouldBlock,
585 @@ -1307,6 +1313,10 @@ SSL_SetURL(PRFileDesc *fd, const char *url)
586 SECStatus
587 SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList)
588 {
589 + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
590 + PR_NOT_REACHED("not implemented");
591 + return SECFailure;
592 +#if 0
593 sslSocket * ss = ssl_FindSocket(fd);
594 CERTDistNames *names = NULL;
595
596 @@ -1334,6 +1344,7 @@ SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList )
597 ssl_Release1stHandshakeLock(ss);
598
599 return SECSuccess;
600 +#endif
601 }
602
603 /*
604 diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/s sl/sslsock.c
605 index aab48d6..c4611a0 100644
606 --- a/mozilla/security/nss/lib/ssl/sslsock.c
607 +++ b/mozilla/security/nss/lib/ssl/sslsock.c
608 @@ -163,6 +163,7 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */
609 ** default settings for socket enables
610 */
611 static sslOptions ssl_defaults = {
612 + { siBuffer, NULL, 0 }, /* nextProtoNego */
613 PR_TRUE, /* useSecurity */
614 PR_FALSE, /* useSocks */
615 PR_FALSE, /* requestCertificate */
616 @@ -183,6 +184,7 @@ static sslOptions ssl_defaults = {
617 PR_FALSE, /* enableDeflate */
618 2, /* enableRenegotiation (default: requires extension) */
619 PR_FALSE, /* requireSafeNegotiation */
620 + PR_FALSE, /* enableFalseStart */
621 };
622
623 sslSessionIDLookupFunc ssl_sid_lookup;
624 @@ -437,6 +439,10 @@ ssl_DestroySocketContents(sslSocket *ss)
625 ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
626 ss->ephemeralECDHKeyPair = NULL;
627 }
628 + if (ss->opt.nextProtoNego.data) {
629 + PORT_Free(ss->opt.nextProtoNego.data);
630 + ss->opt.nextProtoNego.data = NULL;
631 + }
632 PORT_Assert(!ss->xtnData.sniNameArr);
633 if (ss->xtnData.sniNameArr) {
634 PORT_Free(ss->xtnData.sniNameArr);
635 @@ -728,6 +734,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
636 ss->opt.requireSafeNegotiation = on;
637 break;
638
639 + case SSL_ENABLE_FALSE_START:
640 + ss->opt.enableFalseStart = on;
641 + break;
642 +
643 default:
644 PORT_SetError(SEC_ERROR_INVALID_ARGS);
645 rv = SECFailure;
646 @@ -791,6 +801,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
647 on = ss->opt.enableRenegotiation; break;
648 case SSL_REQUIRE_SAFE_NEGOTIATION:
649 on = ss->opt.requireSafeNegotiation; break;
650 + case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break;
651
652 default:
653 PORT_SetError(SEC_ERROR_INVALID_ARGS);
654 @@ -841,6 +852,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
655 case SSL_REQUIRE_SAFE_NEGOTIATION:
656 on = ssl_defaults.requireSafeNegotiation;
657 break;
658 + case SSL_ENABLE_FALSE_START: on = ssl_defaults.enableFalseStart; break;
659
660 default:
661 PORT_SetError(SEC_ERROR_INVALID_ARGS);
662 @@ -984,6 +996,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
663 ssl_defaults.requireSafeNegotiation = on;
664 break;
665
666 + case SSL_ENABLE_FALSE_START:
667 + ssl_defaults.enableFalseStart = on;
668 + break;
669 +
670 default:
671 PORT_SetError(SEC_ERROR_INVALID_ARGS);
672 return SECFailure;
673 @@ -1255,9 +1271,83 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
674 return fd;
675 }
676
677 +/* SSL_SetNextProtoNego sets the list of supported protocols for the given
678 + * socket. The list is a series of 8-bit, length prefixed strings. */
679 +SECStatus
680 +SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
681 + unsigned short length)
682 +{
683 + sslSocket *ss = ssl_FindSocket(fd);
684 +
685 + if (!ss) {
686 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", SSL_GETPID() ,
687 + fd));
688 + return SECFailure;
689 + }
690 +
691 + if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess)
692 + return SECFailure;
693 +
694 + ssl_GetSSL3HandshakeLock(ss);
695 + if (ss->opt.nextProtoNego.data)
696 + PORT_Free(ss->opt.nextProtoNego.data);
697 + ss->opt.nextProtoNego.data = PORT_Alloc(length);
698 + if (!ss->opt.nextProtoNego.data) {
699 + ssl_ReleaseSSL3HandshakeLock(ss);
700 + return SECFailure;
701 + }
702 + memcpy(ss->opt.nextProtoNego.data, data, length);
703 + ss->opt.nextProtoNego.len = length;
704 + ss->opt.nextProtoNego.type = siBuffer;
705 + ssl_ReleaseSSL3HandshakeLock(ss);
706 +
707 + return SECSuccess;
708 +}
709 +
710 +/* SSL_GetNextProto reads the resulting Next Protocol Negotiation result for
711 + * the given socket. It's only valid to call this once the handshake has
712 + * completed.
713 + *
714 + * state is set to one of the SSL_NEXT_PROTO_* constants. The negotiated
715 + * protocol, if any, is written into buf, which must be at least buf_len
716 + * bytes long. If the negotiated protocol is longer than this, it is truncated.
717 + * The number of bytes copied is written into length.
718 + */
719 +SECStatus
720 +SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf,
721 + unsigned int *length, unsigned int buf_len)
722 +{
723 + sslSocket *ss = ssl_FindSocket(fd);
724 +
725 + if (!ss) {
726 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(),
727 + fd));
728 + return SECFailure;
729 + }
730 +
731 + *state = ss->ssl3.nextProtoState;
732 +
733 + if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
734 + ss->ssl3.nextProto.data) {
735 + *length = ss->ssl3.nextProto.len;
736 + if (*length > buf_len)
737 + *length = buf_len;
738 + PORT_Memcpy(buf, ss->ssl3.nextProto.data, *length);
739 + } else {
740 + *length = 0;
741 + }
742 +
743 + return SECSuccess;
744 +}
745 +
746 PRFileDesc *
747 SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
748 {
749 + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
750 + PR_NOT_REACHED("not implemented");
751 + return NULL;
752 +
753 +#if 0
754 sslSocket * sm = NULL, *ss = NULL;
755 int i;
756 sslServerCerts * mc = sm->serverCerts;
757 @@ -1360,6 +1450,7 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
758 return fd;
759 loser:
760 return NULL;
761 +#endif
762 }
763
764 /************************************************************************/
765 diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/ sslt.h
766 index c7d4553..f6e0b62 100644
767 --- a/mozilla/security/nss/lib/ssl/sslt.h
768 +++ b/mozilla/security/nss/lib/ssl/sslt.h
769 @@ -203,9 +203,10 @@ typedef enum {
770 ssl_ec_point_formats_xtn = 11,
771 #endif
772 ssl_session_ticket_xtn = 35,
773 + ssl_next_proto_neg_xtn = 13172,
774 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
775 } SSLExtensionType;
776
777 -#define SSL_MAX_EXTENSIONS 5
778 +#define SSL_MAX_EXTENSIONS 6
779
780 #endif /* __sslt_h_ */
781 diff --git a/mozilla/security/nss/tests/ssl/sslstress.txt b/mozilla/security/nss /tests/ssl/sslstress.txt
782 index 9a3aae8..c2a5c76 100644
783 --- a/mozilla/security/nss/tests/ssl/sslstress.txt
784 +++ b/mozilla/security/nss/tests/ssl/sslstress.txt
785 @@ -42,9 +42,11 @@
786 noECC 0 _ -c_1000_-C_A Stress SSL2 RC4 128 with MD5
787 noECC 0 _ -c_1000_-C_c_-T Stress SSL3 RC4 128 with MD5
788 noECC 0 _ -c_1000_-C_c Stress TLS RC4 128 with MD5
789 + noECC 0 _ -c_1000_-C_c_-h Stress TLS RC4 128 with MD5 (false start)
790 noECC 0 -u -2_-c_1000_-C_c_-u Stress TLS RC4 128 with MD5 (session ticket)
791 noECC 0 -z -2_-c_1000_-C_c_-z Stress TLS RC4 128 with MD5 (compression)
792 noECC 0 -u_-z -2_-c_1000_-C_c_-u_-z Stress TLS RC4 128 with MD5 (session ticket, compression)
793 + noECC 0 -u_-z -2_-c_1000_-C_c_-u_-z_-h Stress TLS RC4 128 with MD5 (session ticket, compression, false start)
794 SNI 0 -u_-a_Host-sni.Dom -2_-3_-c_1000_-C_c_-u Stress TLS RC4 128 with MD5 (session ticket, SNI)
795
796 #
797 @@ -55,7 +57,9 @@
798 noECC 0 -r_-r -c_100_-C_c_-N_-n_TestUser Stress TLS RC4 128 w ith MD5 (no reuse, client auth)
799 noECC 0 -r_-r_-u -2_-c_100_-C_c_-n_TestUser_-u Stress TLS RC4 128 w ith MD5 (session ticket, client auth)
800 noECC 0 -r_-r_-z -2_-c_100_-C_c_-n_TestUser_-z Stress TLS RC4 128 w ith MD5 (compression, client auth)
801 + noECC 0 -r_-r_-z -2_-c_100_-C_c_-n_TestUser_-z_-h Stress TLS RC4 12 8 with MD5 (compression, client auth, false start)
802 noECC 0 -r_-r_-u_-z -2_-c_100_-C_c_-n_TestUser_-u_-z Stress TLS RC4 12 8 with MD5 (session ticket, compression, client auth)
803 + noECC 0 -r_-r_-u_-z -2_-c_100_-C_c_-n_TestUser_-u_-z_-h Stress TLS RC4 128 with MD5 (session ticket, compression, client auth, false start)
804 SNI 0 -r_-r_-u_-a_Host-sni.Dom -2_-3_-c_1000_-C_c_-u Stress TLS RC4 1 28 with MD5 (session ticket, SNI, client auth, default virt host)
805 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, c hange virt host)
806
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698