Chromium Code Reviews| 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 |