| 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 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |