| 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 |