From 62a03ea81ab7a2fe8ff79275427f3353a75e3a4f Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sun, 7 Feb 2016 05:10:18 -0500 Subject: Make SRP6 support optional in TLS Remove SRP_SHA from the default policy, since normal applications do not need it. Removes nullptr initializers of unique_ptrs in the Server_Key_Exchange constructor, that's the default unique_ptr already. --- src/lib/tls/info.txt | 1 - src/lib/tls/msg_client_hello.cpp | 21 +++++++++++++++++++-- src/lib/tls/msg_client_kex.cpp | 15 ++++++++++++--- src/lib/tls/msg_server_kex.cpp | 18 ++++++++---------- src/lib/tls/tls_extensions.cpp | 6 ++++++ src/lib/tls/tls_extensions.h | 2 ++ src/lib/tls/tls_handshake_state.cpp | 4 ++++ src/lib/tls/tls_messages.h | 17 +++++++++++++++-- src/lib/tls/tls_policy.cpp | 4 ++-- src/lib/tls/tls_server.cpp | 4 ++++ 10 files changed, 72 insertions(+), 20 deletions(-) diff --git a/src/lib/tls/info.txt b/src/lib/tls/info.txt index 50b6dbbdf..a43d5619a 100644 --- a/src/lib/tls/info.txt +++ b/src/lib/tls/info.txt @@ -50,6 +50,5 @@ rng rsa sha1 sha2_32 -srp6 x509 diff --git a/src/lib/tls/msg_client_hello.cpp b/src/lib/tls/msg_client_hello.cpp index 43ab84f33..23807215f 100644 --- a/src/lib/tls/msg_client_hello.cpp +++ b/src/lib/tls/msg_client_hello.cpp @@ -82,7 +82,7 @@ Client_Hello::Client_Hello(Handshake_IO& io, { m_extensions.add(new Extended_Master_Secret); m_extensions.add(new Renegotiation_Extension(reneg_info)); - m_extensions.add(new SRP_Identifier(srp_identifier)); + m_extensions.add(new Server_Name_Indicator(hostname)); m_extensions.add(new Session_Ticket()); m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves())); @@ -97,6 +97,15 @@ Client_Hello::Client_Hello(Handshake_IO& io, if(reneg_info.empty() && !next_protocols.empty()) m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols)); +#if defined(BOTAN_HAS_SRP6) + m_extensions.add(new SRP_Identifier(srp_identifier)); +#else + if(!srp_identifier.empty()) + { + throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled"); + } +#endif + BOTAN_ASSERT(policy.acceptable_protocol_version(version), "Our policy accepts the version we are offering"); @@ -136,7 +145,6 @@ Client_Hello::Client_Hello(Handshake_IO& io, m_extensions.add(new Extended_Master_Secret); m_extensions.add(new Renegotiation_Extension(reneg_info)); - m_extensions.add(new SRP_Identifier(session.srp_identifier())); m_extensions.add(new Server_Name_Indicator(session.server_info().hostname())); m_extensions.add(new Session_Ticket(session.session_ticket())); m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves())); @@ -148,6 +156,15 @@ Client_Hello::Client_Hello(Handshake_IO& io, if(reneg_info.empty() && !next_protocols.empty()) m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols)); +#if defined(BOTAN_HAS_SRP6) + m_extensions.add(new SRP_Identifier(session.srp_identifier())); +#else + if(!session.srp_identifier().empty()) + { + throw Invalid_State("Attempting to resume SRP session but TLS-SRP support disabled"); + } +#endif + hash.update(io.send(*this)); } diff --git a/src/lib/tls/msg_client_kex.cpp b/src/lib/tls/msg_client_kex.cpp index 68809f22f..4bec9f3be 100644 --- a/src/lib/tls/msg_client_kex.cpp +++ b/src/lib/tls/msg_client_kex.cpp @@ -10,14 +10,19 @@ #include #include #include +#include +#include +#include + #include + #include #include #include + +#if defined(BOTAN_HAS_SRP6) #include -#include -#include -#include +#endif namespace Botan { @@ -166,6 +171,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_key_material, priv_key.public_value(), 1); } +#if defined(BOTAN_HAS_SRP6) else if(kex_algo == "SRP_SHA") { const BigInt N = BigInt::decode(reader.get_range(2, 1, 65535)); @@ -193,6 +199,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_key_material, BigInt::encode(srp_vals.first), 2); m_pre_master = srp_vals.second.bits_of(); } +#endif else { throw Internal_Error("Client_Key_Exchange: Unknown kex " + @@ -323,12 +330,14 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector& contents, append_tls_length_value(m_pre_master, zeros, 2); append_tls_length_value(m_pre_master, psk.bits_of(), 2); } +#if defined(BOTAN_HAS_SRP6) else if(kex_algo == "SRP_SHA") { SRP6_Server_Session& srp = state.server_kex()->server_srp_params(); m_pre_master = srp.step2(BigInt::decode(reader.get_range(2, 0, 65535))).bits_of(); } +#endif else if(kex_algo == "DH" || kex_algo == "DHE_PSK" || kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") { diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp index 0c3b5c704..fcff7349e 100644 --- a/src/lib/tls/msg_server_kex.cpp +++ b/src/lib/tls/msg_server_kex.cpp @@ -12,11 +12,14 @@ #include #include #include +#include + #include #include -#include + +#if defined(BOTAN_HAS_SRP6) #include -#include +#endif namespace Botan { @@ -86,6 +89,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, m_kex_key.reset(ecdh.release()); } +#if defined(BOTAN_HAS_SRP6) else if(kex_algo == "SRP_SHA") { const std::string srp_identifier = state.client_hello()->srp_identifier(); @@ -115,6 +119,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_params, salt, 1); append_tls_length_value(m_params, BigInt::encode(B), 2); } +#endif else if(kex_algo != "PSK") throw Internal_Error("Server_Key_Exchange: Unknown kex type " + kex_algo); @@ -142,8 +147,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, Server_Key_Exchange::Server_Key_Exchange(const std::vector& buf, const std::string& kex_algo, const std::string& sig_algo, - Protocol_Version version) : - m_kex_key(nullptr), m_srp_params(nullptr) + Protocol_Version version) { TLS_Data_Reader reader("ServerKeyExchange", buf); @@ -249,12 +253,6 @@ const Private_Key& Server_Key_Exchange::server_kex_key() const return *m_kex_key; } -// Only valid for SRP negotiation -SRP6_Server_Session& Server_Key_Exchange::server_srp_params() const - { - BOTAN_ASSERT_NONNULL(m_srp_params); - return *m_srp_params; - } } } diff --git a/src/lib/tls/tls_extensions.cpp b/src/lib/tls/tls_extensions.cpp index b81a0dcb9..35c39ddab 100644 --- a/src/lib/tls/tls_extensions.cpp +++ b/src/lib/tls/tls_extensions.cpp @@ -24,8 +24,10 @@ Extension* make_extension(TLS_Data_Reader& reader, case TLSEXT_SERVER_NAME_INDICATION: return new Server_Name_Indicator(reader, size); +#if defined(BOTAN_HAS_SRP6) case TLSEXT_SRP_IDENTIFIER: return new SRP_Identifier(reader, size); +#endif case TLSEXT_USABLE_ELLIPTIC_CURVES: return new Supported_Elliptic_Curves(reader, size); @@ -175,6 +177,8 @@ std::vector Server_Name_Indicator::serialize() const return buf; } +#if defined(BOTAN_HAS_SRP6) + SRP_Identifier::SRP_Identifier(TLS_Data_Reader& reader, u16bit extension_size) { @@ -196,6 +200,8 @@ std::vector SRP_Identifier::serialize() const return buf; } +#endif + Renegotiation_Extension::Renegotiation_Extension(TLS_Data_Reader& reader, u16bit extension_size) { diff --git a/src/lib/tls/tls_extensions.h b/src/lib/tls/tls_extensions.h index a4ca31410..5a8aff9de 100644 --- a/src/lib/tls/tls_extensions.h +++ b/src/lib/tls/tls_extensions.h @@ -94,6 +94,7 @@ class Server_Name_Indicator final : public Extension std::string m_sni_host_name; }; +#if defined(BOTAN_HAS_SRP6) /** * SRP identifier extension (RFC 5054) */ @@ -119,6 +120,7 @@ class SRP_Identifier final : public Extension private: std::string m_srp_identifier; }; +#endif /** * Renegotiation Indication Extension (RFC 5746) diff --git a/src/lib/tls/tls_handshake_state.cpp b/src/lib/tls/tls_handshake_state.cpp index b085e378a..3799c9e7d 100644 --- a/src/lib/tls/tls_handshake_state.cpp +++ b/src/lib/tls/tls_handshake_state.cpp @@ -325,12 +325,16 @@ Handshake_State::get_next_handshake_msg() std::string Handshake_State::srp_identifier() const { +#if defined(BOTAN_HAS_SRP6) + // Authenticated via the successful key exchange if(ciphersuite().valid() && ciphersuite().kex_algo() == "SRP_SHA") return client_hello()->srp_identifier(); +#endif return ""; } + std::vector Handshake_State::session_ticket() const { if(new_session_ticket() && !new_session_ticket()->ticket().empty()) diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h index 739eca23e..c648df720 100644 --- a/src/lib/tls/tls_messages.h +++ b/src/lib/tls/tls_messages.h @@ -22,7 +22,10 @@ namespace Botan { class Credentials_Manager; + +#if defined(BOTAN_HAS_SRP6) class SRP6_Server_Session; +#endif namespace TLS { @@ -95,12 +98,14 @@ class Client_Hello final : public Handshake_Message return ""; } +#if defined(BOTAN_HAS_SRP6) std::string srp_identifier() const { if(SRP_Identifier* srp = m_extensions.get()) return srp->identifier(); return ""; } +#endif bool secure_renegotiation() const { @@ -463,8 +468,14 @@ class Server_Key_Exchange final : public Handshake_Message // Only valid for certain kex types const Private_Key& server_kex_key() const; +#if defined(BOTAN_HAS_SRP6) // Only valid for SRP negotiation - SRP6_Server_Session& server_srp_params() const; + SRP6_Server_Session& server_srp_params() const + { + BOTAN_ASSERT_NONNULL(m_srp_params); + return *m_srp_params; + } +#endif Server_Key_Exchange(Handshake_IO& io, Handshake_State& state, @@ -482,8 +493,10 @@ class Server_Key_Exchange final : public Handshake_Message private: std::vector serialize() const override; - std::unique_ptr m_kex_key; +#if defined(BOTAN_HAS_SRP6) std::unique_ptr m_srp_params; +#endif + std::unique_ptr m_kex_key; std::vector m_params; diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp index 096dffb4a..3100db50d 100644 --- a/src/lib/tls/tls_policy.cpp +++ b/src/lib/tls/tls_policy.cpp @@ -64,7 +64,7 @@ std::vector Policy::allowed_macs() const std::vector Policy::allowed_key_exchange_methods() const { return { - "SRP_SHA", + //"SRP_SHA", //"ECDHE_PSK", //"DHE_PSK", //"PSK", @@ -80,7 +80,7 @@ std::vector Policy::allowed_signature_methods() const "ECDSA", "RSA", "DSA", - //"" + //"" (anon) }; } diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp index 6aed40479..5ababe621 100644 --- a/src/lib/tls/tls_server.cpp +++ b/src/lib/tls/tls_server.cpp @@ -84,12 +84,14 @@ bool check_for_resume(Session& session_info, session_info.compression_method())) return false; +#if defined(BOTAN_HAS_SRP6) // client sent a different SRP identity if(client_hello->srp_identifier() != "") { if(client_hello->srp_identifier() != session_info.srp_identifier()) return false; } +#endif // client sent a different SNI hostname if(client_hello->sni_hostname() != "") @@ -160,6 +162,7 @@ u16bit choose_ciphersuite( if(suite.sig_algo() != "" && cert_chains.count(suite.sig_algo()) == 0) continue; +#if defined(BOTAN_HAS_SRP6) /* The client may offer SRP cipher suites in the hello message but omit the SRP extension. If the server would like to select an @@ -171,6 +174,7 @@ u16bit choose_ciphersuite( if(suite.kex_algo() == "SRP_SHA" && client_hello->srp_identifier() == "") throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY, "Client wanted SRP but did not send username"); +#endif return suite_id; } -- cgit v1.2.3