diff options
author | lloyd <[email protected]> | 2012-04-25 13:48:08 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-04-25 13:48:08 +0000 |
commit | b72a44475d06263e1492f8913310b5f29515cba6 (patch) | |
tree | 680752dbd43999cea16851b9c196046d9e5fbd7f /src/tls/s_kex.cpp | |
parent | edca5f211722ea6b9d99b8b5fce4603a1b9b422d (diff) | |
parent | f14a9fdee7902ba1a4c962cfbabe29d5146e7c55 (diff) |
propagate from branch 'net.randombit.botan.tls-state-machine' (head a4741cd07f50a9e1b29b0dd97c6fb8697c038ade)
to branch 'net.randombit.botan.cxx11' (head 116e5ff139c07000be431e07d3472cc8f3919b91)
Diffstat (limited to 'src/tls/s_kex.cpp')
-rw-r--r-- | src/tls/s_kex.cpp | 75 |
1 files changed, 67 insertions, 8 deletions
diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp index 0890cac49..95518aa32 100644 --- a/src/tls/s_kex.cpp +++ b/src/tls/s_kex.cpp @@ -16,6 +16,7 @@ #include <botan/dh.h> #include <botan/ecdh.h> #include <botan/rsa.h> +#include <botan/srp6.h> #include <botan/oids.h> #include <memory> @@ -32,22 +33,22 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, Credentials_Manager& creds, RandomNumberGenerator& rng, const Private_Key* signing_key) : - m_kex_key(0) + m_kex_key(0), m_srp_params(0) { + const std::string hostname = state->client_hello->sni_hostname(); const std::string kex_algo = state->suite.kex_algo(); if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") { std::string identity_hint = - creds.psk_identity_hint("tls-server", - state->client_hello->sni_hostname()); + creds.psk_identity_hint("tls-server", hostname); append_tls_length_value(m_params, identity_hint, 2); } if(kex_algo == "DH" || kex_algo == "DHE_PSK") { - std::unique_ptr<DH_PrivateKey> dh(new DH_PrivateKey(rng, policy.dh_group())); + std::auto_ptr<DH_PrivateKey> dh(new DH_PrivateKey(rng, policy.dh_group())); append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_p()), 2); append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_g()), 2); @@ -70,7 +71,7 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, EC_Group ec_group(curve_name); - std::unique_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group)); + std::auto_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group)); const std::string ecdh_domain_oid = ecdh->domain().get_oid(); const std::string domain = OIDS::lookup(OID(ecdh_domain_oid)); @@ -88,6 +89,35 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, m_kex_key = ecdh.release(); } + else if(kex_algo == "SRP_SHA") + { + const std::string srp_identifier = state->client_hello->srp_identifier(); + + std::string group_id; + BigInt v; + MemoryVector<byte> salt; + + const bool found = creds.srp_verifier("tls-server", hostname, + srp_identifier, + group_id, v, salt, + policy.hide_unknown_users()); + + if(!found) + throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY, + "Unknown SRP user " + srp_identifier); + + m_srp_params = new SRP6_Server_Session; + + BigInt B = m_srp_params->step1(v, group_id, + "SHA-1", rng); + + DL_Group group(group_id); + + append_tls_length_value(m_params, BigInt::encode(group.get_p()), 2); + append_tls_length_value(m_params, BigInt::encode(group.get_g()), 2); + append_tls_length_value(m_params, salt, 1); + append_tls_length_value(m_params, BigInt::encode(B), 2); + } else if(kex_algo != "PSK") throw Internal_Error("Server_Key_Exchange: Unknown kex type " + kex_algo); @@ -116,7 +146,7 @@ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion<byte>& buf, const std::string& kex_algo, const std::string& sig_algo, Protocol_Version version) : - m_kex_key(0) + m_kex_key(0), m_srp_params(0) { if(buf.size() < 6) throw Decoding_Error("Server_Key_Exchange: Packet corrupted"); @@ -160,13 +190,27 @@ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion<byte>& buf, if(name == "") throw Decoding_Error("Server_Key_Exchange: Server sent unknown named curve " + - std::to_string(curve_id)); + to_string(curve_id)); m_params.push_back(curve_type); m_params.push_back(get_byte(0, curve_id)); m_params.push_back(get_byte(1, curve_id)); append_tls_length_value(m_params, ecdh_key, 1); } + else if(kex_algo == "SRP_SHA") + { + // 2 bigints (N,g) then salt, then server B + + const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); + const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); + MemoryVector<byte> salt = reader.get_range<byte>(1, 1, 255); + const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); + + append_tls_length_value(m_params, BigInt::encode(N), 2); + append_tls_length_value(m_params, BigInt::encode(g), 2); + append_tls_length_value(m_params, salt, 1); + append_tls_length_value(m_params, BigInt::encode(B), 2); + } else if(kex_algo != "PSK") throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + kex_algo); @@ -182,6 +226,12 @@ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion<byte>& buf, } } +Server_Key_Exchange::~Server_Key_Exchange() + { + delete m_kex_key; + delete m_srp_params; + } + /** * Serialize a Server Key Exchange message @@ -211,7 +261,7 @@ MemoryVector<byte> Server_Key_Exchange::serialize() const bool Server_Key_Exchange::verify(const X509_Certificate& cert, Handshake_State* state) const { - std::unique_ptr<Public_Key> key(cert.subject_public_key()); + std::auto_ptr<Public_Key> key(cert.subject_public_key()); std::pair<std::string, Signature_Format> format = state->understand_sig_format(key.get(), m_hash_algo, m_sig_algo, false); @@ -230,6 +280,15 @@ const Private_Key& Server_Key_Exchange::server_kex_key() const BOTAN_ASSERT(m_kex_key, "Key is non-NULL"); return *m_kex_key; } + +// Only valid for SRP negotiation +SRP6_Server_Session& Server_Key_Exchange::server_srp_params() + { + BOTAN_ASSERT(m_srp_params, "SRP params are non-NULL"); + return *m_srp_params; + } +} + } } |