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

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

Issue 8156001: net: rework the NPN patch. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ... Created 9 years, 2 months 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 | Annotate | Revision Log
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 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 547
548 /* handle an incoming Next Protocol Negotiation extension. */ 548 /* handle an incoming Next Protocol Negotiation extension. */
549 SECStatus 549 SECStatus
550 ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *dat a) 550 ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *dat a)
551 { 551 {
552 if (data->len != 0) { 552 if (data->len != 0) {
553 /* Clients MUST send an empty NPN extension, if any. */ 553 /* Clients MUST send an empty NPN extension, if any. */
554 return SECFailure; 554 return SECFailure;
555 } 555 }
556 556
557 ss->ssl3.hs.nextProtoNego = PR_TRUE;
558 return SECSuccess; 557 return SECSuccess;
559 } 558 }
560 559
561 /* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none 560 /* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none
562 * of the length may be 0 and the sum of the lengths must equal the length of 561 * of the lengths may be 0 and the sum of the lengths must equal the length of
563 * the block. */ 562 * the block. */
564 SECStatus 563 SECStatus
565 ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) 564 ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length)
566 { 565 {
567 unsigned int offset = 0; 566 unsigned int offset = 0;
568 567
569 while (offset < length) { 568 while (offset < length) {
570 if (data[offset] == 0) { 569 if (data[offset] == 0) {
570 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
571 return SECFailure; 571 return SECFailure;
572 } 572 }
573 offset += (unsigned int)data[offset] + 1; 573 offset += (unsigned int)data[offset] + 1;
574 } 574 }
575 575
576 if (offset > length) 576 if (offset > length) {
577 » PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
577 return SECFailure; 578 return SECFailure;
579 }
578 580
579 return SECSuccess; 581 return SECSuccess;
580 } 582 }
581 583
582 SECStatus 584 SECStatus
583 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, 585 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
584 SECItem *data) 586 SECItem *data)
585 { 587 {
586 unsigned int i, j;
587 SECStatus rv; 588 SECStatus rv;
588 unsigned char *result; 589 unsigned char result[255];
589 590 unsigned int result_len;
590 if (data->len == 0) {
591 » /* The server supports the extension, but doesn't have any
592 » * protocols configured. In this case we request our favoured
593 » * protocol. */
594 » goto pick_first;
595 }
596 591
597 rv = ssl3_ValidateNextProtoNego(data->data, data->len); 592 rv = ssl3_ValidateNextProtoNego(data->data, data->len);
598 if (rv != SECSuccess) 593 if (rv != SECSuccess)
599 return rv; 594 return rv;
600 595
601 /* For each protocol in server preference order, see if we support it. */ 596 rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd,
602 for (i = 0; i < data->len; ) { 597 data->data, data->len,
603 » for (j = 0; j < ss->opt.nextProtoNego.len; ) { 598 result, &result_len);
604 » if (data->data[i] == ss->opt.nextProtoNego.data[j] && 599 if (rv != SECSuccess)
605 » » memcmp(&data->data[i+1], &ss->opt.nextProtoNego.data[j+1], 600 » return rv;
606 » » data->data[i]) == 0) { 601 // If the callback wrote more than allowed to |result| it has corrupted our
607 » » /* We found a match */ 602 // stack.
608 » » ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; 603 PORT_Assert(result_len <= sizeof(result));
609 » » result = &data->data[i];
610 » » goto found;
611 » }
612 » j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1;
613 » }
614 604
615 i += (unsigned int)data->data[i] + 1;
616 }
617
618 pick_first:
619 ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
620 result = ss->opt.nextProtoNego.data;
621
622 found:
623 if (ss->ssl3.nextProto.data) 605 if (ss->ssl3.nextProto.data)
624 PORT_Free(ss->ssl3.nextProto.data); 606 PORT_Free(ss->ssl3.nextProto.data);
625 ss->ssl3.nextProto.data = PORT_Alloc(result[0]); 607 ss->ssl3.nextProto.data = PORT_Alloc(result_len);
626 PORT_Memcpy(ss->ssl3.nextProto.data, result + 1, result[0]); 608 PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len);
627 ss->ssl3.nextProto.len = result[0]; 609 ss->ssl3.nextProto.len = result_len;
628 return SECSuccess; 610 return SECSuccess;
629 } 611 }
630 612
631 PRInt32 613 PRInt32
632 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, 614 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss,
633 PRBool append, 615 PRBool append,
634 PRUint32 maxBytes) 616 PRUint32 maxBytes)
635 { 617 {
636 PRInt32 extension_length; 618 PRInt32 extension_length;
637 619
638 /* Renegotiations do not send this extension. */ 620 /* Renegotiations do not send this extension. */
639 if (ss->opt.nextProtoNego.len == 0 || ss->firstHsDone) { 621 if (!ss->nextProtoCallback || ss->firstHsDone) {
640 return 0; 622 return 0;
641 } 623 }
642 624
643 extension_length = 4; 625 extension_length = 4;
644 626
645 if (append && maxBytes >= extension_length) { 627 if (append && maxBytes >= extension_length) {
646 SECStatus rv; 628 SECStatus rv;
647 rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); 629 rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2);
648 if (rv != SECSuccess) 630 if (rv != SECSuccess)
649 goto loser; 631 goto loser;
(...skipping 1396 matching lines...) Expand 10 before | Expand all | Expand 10 after
2046 2028
2047 /* The echoed extension must be empty. */ 2029 /* The echoed extension must be empty. */
2048 if (data->len != 0) 2030 if (data->len != 0)
2049 return SECFailure; 2031 return SECFailure;
2050 2032
2051 /* Keep track of negotiated extensions. */ 2033 /* Keep track of negotiated extensions. */
2052 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 2034 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
2053 2035
2054 return SECSuccess; 2036 return SECSuccess;
2055 } 2037 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698