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 |