OLD | NEW |
---|---|
1 /* | 1 /* |
2 * SSL3 Protocol | 2 * SSL3 Protocol |
3 * | 3 * |
4 * This Source Code Form is subject to the terms of the Mozilla Public | 4 * This Source Code Form is subject to the terms of the Mozilla Public |
5 * License, v. 2.0. If a copy of the MPL was not distributed with this | 5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
7 | 7 |
8 /* TLS extension code moved here from ssl3ecc.c */ | 8 /* TLS extension code moved here from ssl3ecc.c */ |
9 | 9 |
10 #include "nssrenam.h" | 10 #include "nssrenam.h" |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
717 return extension_length; | 717 return extension_length; |
718 | 718 |
719 loser: | 719 loser: |
720 return -1; | 720 return -1; |
721 } | 721 } |
722 | 722 |
723 static PRInt32 | 723 static PRInt32 |
724 ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) | 724 ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) |
725 { | 725 { |
726 PRInt32 extension_length; | 726 PRInt32 extension_length; |
727 unsigned char *alpn_protos = NULL; | |
727 | 728 |
728 /* Renegotiations do not send this extension. */ | 729 /* Renegotiations do not send this extension. */ |
729 if (!ss->opt.nextProtoNego.data || ss->firstHsDone) { | 730 if (!ss->opt.nextProtoNego.data || ss->firstHsDone) { |
730 return 0; | 731 return 0; |
731 } | 732 } |
732 | 733 |
733 extension_length = 2 /* extension type */ + 2 /* extension length */ + | 734 extension_length = 2 /* extension type */ + 2 /* extension length */ + |
734 2 /* protocol name list length */ + | 735 2 /* protocol name list length */ + |
735 ss->opt.nextProtoNego.len; | 736 ss->opt.nextProtoNego.len; |
736 | 737 |
737 if (append && maxBytes >= extension_length) { | 738 if (append && maxBytes >= extension_length) { |
739 /* NPN requires that the client's fallback protocol is first in the | |
740 * list. However, ALPN sends protocols in preference order. So we | |
741 * allocate a buffer and move the first protocol to the end of the | |
742 * list. */ | |
wtc
2013/08/05 22:37:35
This policy implies the fallback protocol is the l
agl
2013/08/06 17:06:43
I can imagine a case where it's not true, but it w
| |
738 SECStatus rv; | 743 SECStatus rv; |
744 const size_t len = ss->opt.nextProtoNego.len; | |
wtc
2013/08/05 22:37:35
Nit: |len| can be an unsigned int. I wonder if pas
agl
2013/08/06 17:06:43
Changed to unsigned int (and |i|).
| |
745 size_t i; | |
746 | |
747 alpn_protos = PORT_Alloc(len); | |
748 if (alpn_protos == NULL) { | |
749 return SECFailure; | |
750 } | |
751 if (len > 0) { | |
752 /* Each protocol string is prefixed with a single byte length. */ | |
wtc
2013/08/05 22:37:35
Nit: the variable |i| can be declared inside this
agl
2013/08/06 17:06:43
Done.
| |
753 i = ss->opt.nextProtoNego.data[0] + 1; | |
754 if (i <= len) { | |
755 memcpy(alpn_protos, &ss->opt.nextProtoNego.data[i], len - i); | |
756 memcpy(alpn_protos + len-i, ss->opt.nextProtoNego.data, i); | |
wtc
2013/08/05 22:37:35
Nit: len-i => len - i
Are you trying to avoid a l
agl
2013/08/06 17:06:43
It was just the logical grouping in my mind. Chang
| |
757 } else { | |
758 /* This seems to be invalid data so we'll send as-is. */ | |
759 memcpy(alpn_protos, ss->opt.nextProtoNego.data, len); | |
760 } | |
761 } | |
762 | |
739 rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); | 763 rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); |
740 if (rv != SECSuccess) | 764 if (rv != SECSuccess) |
741 goto loser; | 765 goto loser; |
742 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); | 766 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); |
743 if (rv != SECSuccess) | 767 if (rv != SECSuccess) |
744 goto loser; | 768 goto loser; |
745 » rv = ssl3_AppendHandshakeVariable(ss, ss->opt.nextProtoNego.data, | 769 » rv = ssl3_AppendHandshakeVariable(ss, alpn_protos, len, 2); |
746 » » » » » ss->opt.nextProtoNego.len, 2); | 770 » PORT_Free(alpn_protos); |
771 » alpn_protos = NULL; | |
747 if (rv != SECSuccess) | 772 if (rv != SECSuccess) |
748 goto loser; | 773 goto loser; |
749 ss->xtnData.advertised[ss->xtnData.numAdvertised++] = | 774 ss->xtnData.advertised[ss->xtnData.numAdvertised++] = |
750 ssl_app_layer_protocol_xtn; | 775 ssl_app_layer_protocol_xtn; |
751 } else if (maxBytes < extension_length) { | 776 } else if (maxBytes < extension_length) { |
752 return 0; | 777 return 0; |
753 } | 778 } |
754 | 779 |
755 return extension_length; | 780 return extension_length; |
756 | 781 |
757 loser: | 782 loser: |
783 if (alpn_protos) | |
784 PORT_Free(alpn_protos); | |
758 return -1; | 785 return -1; |
759 } | 786 } |
760 | 787 |
761 static SECStatus | 788 static SECStatus |
762 ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, | 789 ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, |
763 SECItem *data) | 790 SECItem *data) |
764 { | 791 { |
765 PORT_Assert(ss->getChannelID != NULL); | 792 PORT_Assert(ss->getChannelID != NULL); |
766 | 793 |
767 if (data->len) { | 794 if (data->len) { |
(...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2264 } else if (maxBytes < extension_length) { | 2291 } else if (maxBytes < extension_length) { |
2265 PORT_Assert(0); | 2292 PORT_Assert(0); |
2266 return 0; | 2293 return 0; |
2267 } | 2294 } |
2268 | 2295 |
2269 return extension_length; | 2296 return extension_length; |
2270 | 2297 |
2271 loser: | 2298 loser: |
2272 return -1; | 2299 return -1; |
2273 } | 2300 } |
OLD | NEW |