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

Side by Side Diff: net/third_party/nss/ssl/ssl3ext.c

Issue 415005: Linux: add next-protocol-negotiation to libssl. (Closed)
Patch Set: Addressing wtc's comments. Created 11 years 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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698