| 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) { |
| 571 return SECFailure; | 570 return SECFailure; |
| 572 } | 571 } |
| 573 offset += (unsigned int)data[offset] + 1; | 572 offset += (unsigned int)data[offset] + 1; |
| 574 } | 573 } |
| 575 | 574 |
| 576 if (offset > length) | 575 if (offset > length) |
| 577 return SECFailure; | 576 return SECFailure; |
| 578 | 577 |
| 579 return SECSuccess; | 578 return SECSuccess; |
| 580 } | 579 } |
| 581 | 580 |
| 582 SECStatus | 581 SECStatus |
| 583 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, | 582 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, |
| 584 SECItem *data) | 583 SECItem *data) |
| 585 { | 584 { |
| 586 unsigned int i, j; | |
| 587 SECStatus rv; | 585 SECStatus rv; |
| 588 unsigned char *result; | 586 unsigned char result[255]; |
| 589 | 587 unsigned char 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 | 588 |
| 597 rv = ssl3_ValidateNextProtoNego(data->data, data->len); | 589 rv = ssl3_ValidateNextProtoNego(data->data, data->len); |
| 598 if (rv != SECSuccess) | 590 if (rv != SECSuccess) |
| 599 return rv; | 591 return rv; |
| 600 | 592 |
| 601 /* For each protocol in server preference order, see if we support it. */ | 593 rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, |
| 602 for (i = 0; i < data->len; ) { | 594 data->data, data->len, |
| 603 » for (j = 0; j < ss->opt.nextProtoNego.len; ) { | 595 result, &result_len); |
| 604 » if (data->data[i] == ss->opt.nextProtoNego.data[j] && | 596 if (rv != SECSuccess) |
| 605 » » memcmp(&data->data[i+1], &ss->opt.nextProtoNego.data[j+1], | 597 » return rv; |
| 606 » » data->data[i]) == 0) { | |
| 607 » » /* We found a match */ | |
| 608 » » ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; | |
| 609 » » result = &data->data[i]; | |
| 610 » » goto found; | |
| 611 » } | |
| 612 » j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1; | |
| 613 » } | |
| 614 | 598 |
| 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) | 599 if (ss->ssl3.nextProto.data) |
| 624 PORT_Free(ss->ssl3.nextProto.data); | 600 PORT_Free(ss->ssl3.nextProto.data); |
| 625 ss->ssl3.nextProto.data = PORT_Alloc(result[0]); | 601 ss->ssl3.nextProto.data = PORT_Alloc(result_len); |
| 626 PORT_Memcpy(ss->ssl3.nextProto.data, result + 1, result[0]); | 602 PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len); |
| 627 ss->ssl3.nextProto.len = result[0]; | 603 ss->ssl3.nextProto.len = result_len; |
| 628 return SECSuccess; | 604 return SECSuccess; |
| 629 } | 605 } |
| 630 | 606 |
| 631 PRInt32 | 607 PRInt32 |
| 632 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, | 608 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, |
| 633 PRBool append, | 609 PRBool append, |
| 634 PRUint32 maxBytes) | 610 PRUint32 maxBytes) |
| 635 { | 611 { |
| 636 PRInt32 extension_length; | 612 PRInt32 extension_length; |
| 637 | 613 |
| 638 /* Renegotiations do not send this extension. */ | 614 /* Renegotiations do not send this extension. */ |
| 639 if (ss->opt.nextProtoNego.len == 0 || ss->firstHsDone) { | 615 if (!ss->nextProtoCallback || ss->firstHsDone) { |
| 640 return 0; | 616 return 0; |
| 641 } | 617 } |
| 642 | 618 |
| 643 extension_length = 4; | 619 extension_length = 4; |
| 644 | 620 |
| 645 if (append && maxBytes >= extension_length) { | 621 if (append && maxBytes >= extension_length) { |
| 646 SECStatus rv; | 622 SECStatus rv; |
| 647 rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); | 623 rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); |
| 648 if (rv != SECSuccess) | 624 if (rv != SECSuccess) |
| 649 goto loser; | 625 goto loser; |
| (...skipping 1396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2046 | 2022 |
| 2047 /* The echoed extension must be empty. */ | 2023 /* The echoed extension must be empty. */ |
| 2048 if (data->len != 0) | 2024 if (data->len != 0) |
| 2049 return SECFailure; | 2025 return SECFailure; |
| 2050 | 2026 |
| 2051 /* Keep track of negotiated extensions. */ | 2027 /* Keep track of negotiated extensions. */ |
| 2052 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | 2028 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
| 2053 | 2029 |
| 2054 return SECSuccess; | 2030 return SECSuccess; |
| 2055 } | 2031 } |
| OLD | NEW |