OLD | NEW |
---|---|
(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 | |
OLD | NEW |