OLD | NEW |
1 /* | 1 /* |
2 * SSL3 Protocol | 2 * SSL3 Protocol |
3 * | 3 * |
4 * ***** BEGIN LICENSE BLOCK ***** | 4 * ***** BEGIN LICENSE BLOCK ***** |
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
6 * | 6 * |
7 * The contents of this file are subject to the Mozilla Public License Version | 7 * The contents of this file are subject to the Mozilla Public License Version |
8 * 1.1 (the "License"); you may not use this file except in compliance with | 8 * 1.1 (the "License"); you may not use this file except in compliance with |
9 * the License. You may obtain a copy of the License at | 9 * the License. You may obtain a copy of the License at |
10 * http://www.mozilla.org/MPL/ | 10 * http://www.mozilla.org/MPL/ |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 * In the second generation, this table will be dynamic, and functions | 222 * In the second generation, this table will be dynamic, and functions |
223 * will be registered here. | 223 * will be registered here. |
224 */ | 224 */ |
225 static const ssl3HelloExtensionHandler clientHelloHandlers[] = { | 225 static const ssl3HelloExtensionHandler clientHelloHandlers[] = { |
226 { server_name_xtn, &ssl3_HandleServerNameXtn }, | 226 { server_name_xtn, &ssl3_HandleServerNameXtn }, |
227 #ifdef NSS_ENABLE_ECC | 227 #ifdef NSS_ENABLE_ECC |
228 { elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, | 228 { elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, |
229 { ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, | 229 { ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, |
230 #endif | 230 #endif |
231 { session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, | 231 { session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, |
| 232 { next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, |
232 { -1, NULL } | 233 { -1, NULL } |
233 }; | 234 }; |
234 | 235 |
235 static const ssl3HelloExtensionHandler serverHelloHandlers[] = { | 236 static const ssl3HelloExtensionHandler serverHelloHandlers[] = { |
236 { server_name_xtn, &ssl3_HandleServerNameXtn }, | 237 { server_name_xtn, &ssl3_HandleServerNameXtn }, |
237 /* TODO: add a handler for ec_point_formats_xtn */ | 238 /* TODO: add a handler for ec_point_formats_xtn */ |
238 { session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, | 239 { session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, |
| 240 { next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, |
239 { -1, NULL } | 241 { -1, NULL } |
240 }; | 242 }; |
241 | 243 |
242 /* Table of functions to format TLS hello extensions, one per extension. | 244 /* Table of functions to format TLS hello extensions, one per extension. |
243 * This static table is for the formatting of client hello extensions. | 245 * This static table is for the formatting of client hello extensions. |
244 * The server's table of hello senders is dynamic, in the socket struct, | 246 * The server's table of hello senders is dynamic, in the socket struct, |
245 * and sender functions are registered there. | 247 * and sender functions are registered there. |
246 */ | 248 */ |
247 static const | 249 static const |
248 ssl3HelloExtensionSender clientHelloSenders[MAX_EXTENSIONS] = { | 250 ssl3HelloExtensionSender clientHelloSenders[MAX_EXTENSIONS] = { |
249 { server_name_xtn, &ssl3_SendServerNameXtn }, | 251 { server_name_xtn, &ssl3_SendServerNameXtn }, |
250 #ifdef NSS_ENABLE_ECC | 252 #ifdef NSS_ENABLE_ECC |
251 { elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, | 253 { elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, |
252 { ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, | 254 { ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, |
253 #else | 255 #else |
254 { -1, NULL }, | 256 { -1, NULL }, |
255 { -1, NULL }, | 257 { -1, NULL }, |
256 #endif | 258 #endif |
257 { session_ticket_xtn, ssl3_SendSessionTicketXtn } | 259 { session_ticket_xtn, ssl3_SendSessionTicketXtn }, |
| 260 { next_proto_neg_xtn, ssl3_ClientSendNextProtoNegoXtn } |
258 }; | 261 }; |
259 | 262 |
260 static PRBool | 263 static PRBool |
261 arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type) | 264 arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type) |
262 { | 265 { |
263 int i; | 266 int i; |
264 for (i = 0; i < len; i++) { | 267 for (i = 0; i < len; i++) { |
265 if (ex_type == array[i]) | 268 if (ex_type == array[i]) |
266 return PR_TRUE; | 269 return PR_TRUE; |
267 } | 270 } |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 PORT_Assert(0); | 408 PORT_Assert(0); |
406 return 0; | 409 return 0; |
407 } | 410 } |
408 return extension_length; | 411 return extension_length; |
409 | 412 |
410 loser: | 413 loser: |
411 ss->xtnData.ticketTimestampVerified = PR_FALSE; | 414 ss->xtnData.ticketTimestampVerified = PR_FALSE; |
412 return -1; | 415 return -1; |
413 } | 416 } |
414 | 417 |
| 418 /* handle an incoming Next Protocol Negotiation extension. */ |
| 419 SECStatus |
| 420 ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *dat
a) |
| 421 { |
| 422 if (data->len != 0) { |
| 423 /* Clients MUST send an empty NPN extension, if any. */ |
| 424 return SECFailure; |
| 425 } |
| 426 |
| 427 ss->ssl3.hs.nextProtoNego = PR_TRUE; |
| 428 return SECSuccess; |
| 429 } |
| 430 |
| 431 /* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none |
| 432 * of the length may be 0 and the sum of the lengths must equal the length of |
| 433 * the block. */ |
| 434 SECStatus |
| 435 ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) |
| 436 { |
| 437 unsigned int offset = 0; |
| 438 |
| 439 while (offset < length) { |
| 440 if (data[offset] == 0) { |
| 441 return SECFailure; |
| 442 } |
| 443 offset += data[offset] + 1; |
| 444 } |
| 445 |
| 446 if (offset > length) |
| 447 return SECFailure; |
| 448 |
| 449 return SECSuccess; |
| 450 } |
| 451 |
| 452 SECStatus |
| 453 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, |
| 454 SECItem *data) |
| 455 { |
| 456 unsigned int i, j; |
| 457 SECStatus rv; |
| 458 unsigned char *result; |
| 459 |
| 460 if (data->len == 0) { |
| 461 /* The server supports the extension, but doesn't have any |
| 462 * protocols configured. In this case we request our favoured |
| 463 * protocol. */ |
| 464 goto pick_first; |
| 465 } |
| 466 |
| 467 rv = ssl3_ValidateNextProtoNego(data->data, data->len); |
| 468 if (rv != SECSuccess) |
| 469 return rv; |
| 470 |
| 471 /* For each protocol in server preference order, see if we support it. */ |
| 472 for (i = 0; i < data->len; ) { |
| 473 for (j = 0; j < ss->opt.nextProtoNego.len; ) { |
| 474 if (data->data[i] == ss->opt.nextProtoNego.data[j] && |
| 475 memcmp(&data->data[i+1], &ss->opt.nextProtoNego.data[j+1], |
| 476 data->data[i]) == 0) { |
| 477 /* We found a match */ |
| 478 ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; |
| 479 result = &data->data[i]; |
| 480 goto found; |
| 481 } |
| 482 j += ss->opt.nextProtoNego.data[j] + 1; |
| 483 } |
| 484 |
| 485 i += data->data[i] + 1; |
| 486 } |
| 487 |
| 488 pick_first: |
| 489 ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP; |
| 490 result = ss->opt.nextProtoNego.data; |
| 491 |
| 492 found: |
| 493 if (ss->ssl3.nextProto.data) |
| 494 PORT_Free(ss->ssl3.nextProto.data); |
| 495 ss->ssl3.nextProto.data = PORT_Alloc(result[0]); |
| 496 PORT_Memcpy(ss->ssl3.nextProto.data, result + 1, result[0]); |
| 497 ss->ssl3.nextProto.len = result[0]; |
| 498 return SECSuccess; |
| 499 } |
| 500 |
| 501 PRInt32 |
| 502 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, |
| 503 PRBool append, |
| 504 PRUint32 maxBytes) |
| 505 { |
| 506 PRInt32 extension_length; |
| 507 |
| 508 /* Renegotiations do not send this extension. */ |
| 509 if (ss->opt.nextProtoNego.len == 0 || ss->firstHsDone) { |
| 510 return 0; |
| 511 } |
| 512 |
| 513 extension_length = 4; |
| 514 |
| 515 if (append && maxBytes >= extension_length) { |
| 516 SECStatus rv; |
| 517 rv = ssl3_AppendHandshakeNumber(ss, next_proto_neg_xtn, 2); |
| 518 if (rv != SECSuccess) |
| 519 goto loser; |
| 520 rv = ssl3_AppendHandshakeNumber(ss, 0, 2); |
| 521 if (rv != SECSuccess) |
| 522 goto loser; |
| 523 TLSExtensionData *xtnData = &ss->xtnData; |
| 524 xtnData->advertised[xtnData->numAdvertised++] = next_proto_neg_xtn; |
| 525 } else if (maxBytes < extension_length) { |
| 526 return 0; |
| 527 } |
| 528 |
| 529 return extension_length; |
| 530 |
| 531 loser: |
| 532 return -1; |
| 533 } |
| 534 |
415 /* | 535 /* |
416 * NewSessionTicket | 536 * NewSessionTicket |
417 * Called from ssl3_HandleFinished | 537 * Called from ssl3_HandleFinished |
418 */ | 538 */ |
419 SECStatus | 539 SECStatus |
420 ssl3_SendNewSessionTicket(sslSocket *ss) | 540 ssl3_SendNewSessionTicket(sslSocket *ss) |
421 { | 541 { |
422 int i; | 542 int i; |
423 SECStatus rv; | 543 SECStatus rv; |
424 NewSessionTicket ticket; | 544 NewSessionTicket ticket; |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 if (sender->ex_sender) { | 1379 if (sender->ex_sender) { |
1260 PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes); | 1380 PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes); |
1261 if (extLen < 0) | 1381 if (extLen < 0) |
1262 return -1; | 1382 return -1; |
1263 maxBytes -= extLen; | 1383 maxBytes -= extLen; |
1264 total_exten_len += extLen; | 1384 total_exten_len += extLen; |
1265 } | 1385 } |
1266 } | 1386 } |
1267 return total_exten_len; | 1387 return total_exten_len; |
1268 } | 1388 } |
OLD | NEW |