diff options
Diffstat (limited to 'src/lib/tls/msg_client_hello.cpp')
-rw-r--r-- | src/lib/tls/msg_client_hello.cpp | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/src/lib/tls/msg_client_hello.cpp b/src/lib/tls/msg_client_hello.cpp index 69f9a5e11..56e226a40 100644 --- a/src/lib/tls/msg_client_hello.cpp +++ b/src/lib/tls/msg_client_hello.cpp @@ -80,25 +80,27 @@ Client_Hello::Client_Hello(Handshake_IO& io, client_settings.srp_identifier() != "")), m_comp_methods(policy.compression()) { + BOTAN_ASSERT(policy.acceptable_protocol_version(client_settings.protocol_version()), + "Our policy accepts the version we are offering"); + + /* + * Place all empty extensions in front to avoid a bug in some sytems + * which reject hellos when the last extension in the list is empty. + */ m_extensions.add(new Extended_Master_Secret); + m_extensions.add(new Session_Ticket()); + if(policy.negotiate_encrypt_then_mac()) + m_extensions.add(new Encrypt_then_MAC); + m_extensions.add(new Renegotiation_Extension(reneg_info)); m_extensions.add(new Server_Name_Indicator(client_settings.hostname())); - m_extensions.add(new Session_Ticket()); - m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves())); - if(m_version.supports_negotiable_signature_algorithms()) - m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(), - policy.allowed_signature_methods())); + if(reneg_info.empty() && !next_protocols.empty()) + m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols)); if(m_version.is_datagram_protocol()) m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles())); - if(reneg_info.empty() && !next_protocols.empty()) - m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols)); - - if(policy.negotiate_encrypt_then_mac()) - m_extensions.add(new Encrypt_then_MAC); - #if defined(BOTAN_HAS_SRP6) m_extensions.add(new SRP_Identifier(client_settings.srp_identifier())); #else @@ -108,8 +110,11 @@ Client_Hello::Client_Hello(Handshake_IO& io, } #endif - BOTAN_ASSERT(policy.acceptable_protocol_version(client_settings.protocol_version()), - "Our policy accepts the version we are offering"); + m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves())); + + if(m_version.supports_negotiable_signature_algorithms()) + m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(), + policy.allowed_signature_methods())); if(policy.send_fallback_scsv(client_settings.protocol_version())) m_suites.push_back(TLS_FALLBACK_SCSV); @@ -256,6 +261,15 @@ Client_Hello::Client_Hello(const std::vector<byte>& buf) m_extensions.add(new Renegotiation_Extension()); } } + + // Parsing complete, now any additional decoding checks + + if(m_version.supports_negotiable_signature_algorithms() == false) + { + if(m_extensions.has<Signature_Algorithms>()) + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, + "Client sent signature_algorithms extension in version that doesn't support it"); + } } bool Client_Hello::sent_fallback_scsv() const |