Botan  1.11.15
src/lib/tls/msg_server_kex.cpp
Go to the documentation of this file.
00001 /*
00002 * Server Key Exchange Message
00003 * (C) 2004-2010,2012 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/tls_messages.h>
00009 #include <botan/internal/tls_reader.h>
00010 #include <botan/internal/tls_extensions.h>
00011 #include <botan/internal/tls_handshake_io.h>
00012 #include <botan/credentials_manager.h>
00013 #include <botan/loadstor.h>
00014 #include <botan/pubkey.h>
00015 #include <botan/dh.h>
00016 #include <botan/ecdh.h>
00017 #include <botan/rsa.h>
00018 #include <botan/srp6.h>
00019 #include <botan/oids.h>
00020 
00021 namespace Botan {
00022 
00023 namespace TLS {
00024 
00025 /**
00026 * Create a new Server Key Exchange message
00027 */
00028 Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
00029                                          Handshake_State& state,
00030                                          const Policy& policy,
00031                                          Credentials_Manager& creds,
00032                                          RandomNumberGenerator& rng,
00033                                          const Private_Key* signing_key)
00034    {
00035    const std::string hostname = state.client_hello()->sni_hostname();
00036    const std::string kex_algo = state.ciphersuite().kex_algo();
00037 
00038    if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
00039       {
00040       std::string identity_hint =
00041          creds.psk_identity_hint("tls-server", hostname);
00042 
00043       append_tls_length_value(m_params, identity_hint, 2);
00044       }
00045 
00046    if(kex_algo == "DH" || kex_algo == "DHE_PSK")
00047       {
00048       std::unique_ptr<DH_PrivateKey> dh(new DH_PrivateKey(rng, policy.dh_group()));
00049 
00050       append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_p()), 2);
00051       append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_g()), 2);
00052       append_tls_length_value(m_params, dh->public_value(), 2);
00053       m_kex_key.reset(dh.release());
00054       }
00055    else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
00056       {
00057       const std::vector<std::string>& curves =
00058          state.client_hello()->supported_ecc_curves();
00059 
00060       if(curves.empty())
00061          throw Internal_Error("Client sent no ECC extension but we negotiated ECDH");
00062 
00063       const std::string curve_name = policy.choose_curve(curves);
00064 
00065       if(curve_name == "")
00066          throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00067                              "Could not agree on an ECC curve with the client");
00068 
00069       EC_Group ec_group(curve_name);
00070 
00071       std::unique_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group));
00072 
00073       const std::string ecdh_domain_oid = ecdh->domain().get_oid();
00074       const std::string domain = OIDS::lookup(OID(ecdh_domain_oid));
00075 
00076       if(domain == "")
00077          throw Internal_Error("Could not find name of ECDH domain " + ecdh_domain_oid);
00078 
00079       const u16bit named_curve_id = Supported_Elliptic_Curves::name_to_curve_id(domain);
00080 
00081       m_params.push_back(3); // named curve
00082       m_params.push_back(get_byte(0, named_curve_id));
00083       m_params.push_back(get_byte(1, named_curve_id));
00084 
00085       append_tls_length_value(m_params, ecdh->public_value(), 1);
00086 
00087       m_kex_key.reset(ecdh.release());
00088       }
00089    else if(kex_algo == "SRP_SHA")
00090       {
00091       const std::string srp_identifier = state.client_hello()->srp_identifier();
00092 
00093       std::string group_id;
00094       BigInt v;
00095       std::vector<byte> salt;
00096 
00097       const bool found = creds.srp_verifier("tls-server", hostname,
00098                                             srp_identifier,
00099                                             group_id, v, salt,
00100                                             policy.hide_unknown_users());
00101 
00102       if(!found)
00103          throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY,
00104                              "Unknown SRP user " + srp_identifier);
00105 
00106       m_srp_params.reset(new SRP6_Server_Session);
00107 
00108       BigInt B = m_srp_params->step1(v, group_id,
00109                                      "SHA-1", rng);
00110 
00111       DL_Group group(group_id);
00112 
00113       append_tls_length_value(m_params, BigInt::encode(group.get_p()), 2);
00114       append_tls_length_value(m_params, BigInt::encode(group.get_g()), 2);
00115       append_tls_length_value(m_params, salt, 1);
00116       append_tls_length_value(m_params, BigInt::encode(B), 2);
00117       }
00118    else if(kex_algo != "PSK")
00119       throw Internal_Error("Server_Key_Exchange: Unknown kex type " + kex_algo);
00120 
00121    if(state.ciphersuite().sig_algo() != "")
00122       {
00123       BOTAN_ASSERT(signing_key, "Signing key was set");
00124 
00125       std::pair<std::string, Signature_Format> format =
00126          state.choose_sig_format(*signing_key, m_hash_algo, m_sig_algo, false, policy);
00127 
00128       PK_Signer signer(*signing_key, format.first, format.second);
00129 
00130       signer.update(state.client_hello()->random());
00131       signer.update(state.server_hello()->random());
00132       signer.update(params());
00133       m_signature = signer.signature(rng);
00134       }
00135 
00136    state.hash().update(io.send(*this));
00137    }
00138 
00139 /**
00140 * Deserialize a Server Key Exchange message
00141 */
00142 Server_Key_Exchange::Server_Key_Exchange(const std::vector<byte>& buf,
00143                                          const std::string& kex_algo,
00144                                          const std::string& sig_algo,
00145                                          Protocol_Version version) :
00146    m_kex_key(nullptr), m_srp_params(nullptr)
00147    {
00148    if(buf.size() < 6)
00149       throw Decoding_Error("Server_Key_Exchange: Packet corrupted");
00150 
00151    TLS_Data_Reader reader("ServerKeyExchange", buf);
00152 
00153    /*
00154    * We really are just serializing things back to what they were
00155    * before, but unfortunately to know where the signature is we need
00156    * to be able to parse the whole thing anyway.
00157    */
00158 
00159    if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
00160       {
00161       const std::string identity_hint = reader.get_string(2, 0, 65535);
00162       append_tls_length_value(m_params, identity_hint, 2);
00163       }
00164 
00165    if(kex_algo == "DH" || kex_algo == "DHE_PSK")
00166       {
00167       // 3 bigints, DH p, g, Y
00168 
00169       for(size_t i = 0; i != 3; ++i)
00170          {
00171          BigInt v = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
00172          append_tls_length_value(m_params, BigInt::encode(v), 2);
00173          }
00174       }
00175    else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
00176       {
00177       const byte curve_type = reader.get_byte();
00178 
00179       if(curve_type != 3)
00180          throw Decoding_Error("Server_Key_Exchange: Server sent non-named ECC curve");
00181 
00182       const u16bit curve_id = reader.get_u16bit();
00183 
00184       const std::string name = Supported_Elliptic_Curves::curve_id_to_name(curve_id);
00185 
00186       std::vector<byte> ecdh_key = reader.get_range<byte>(1, 1, 255);
00187 
00188       if(name == "")
00189          throw Decoding_Error("Server_Key_Exchange: Server sent unknown named curve " +
00190                               std::to_string(curve_id));
00191 
00192       m_params.push_back(curve_type);
00193       m_params.push_back(get_byte(0, curve_id));
00194       m_params.push_back(get_byte(1, curve_id));
00195       append_tls_length_value(m_params, ecdh_key, 1);
00196       }
00197    else if(kex_algo == "SRP_SHA")
00198       {
00199       // 2 bigints (N,g) then salt, then server B
00200 
00201       const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
00202       const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
00203       std::vector<byte> salt = reader.get_range<byte>(1, 1, 255);
00204       const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
00205 
00206       append_tls_length_value(m_params, BigInt::encode(N), 2);
00207       append_tls_length_value(m_params, BigInt::encode(g), 2);
00208       append_tls_length_value(m_params, salt, 1);
00209       append_tls_length_value(m_params, BigInt::encode(B), 2);
00210       }
00211    else if(kex_algo != "PSK")
00212       throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + kex_algo);
00213 
00214    if(sig_algo != "")
00215       {
00216       if(version.supports_negotiable_signature_algorithms())
00217          {
00218          m_hash_algo = Signature_Algorithms::hash_algo_name(reader.get_byte());
00219          m_sig_algo = Signature_Algorithms::sig_algo_name(reader.get_byte());
00220          }
00221 
00222       m_signature = reader.get_range<byte>(2, 0, 65535);
00223       }
00224 
00225    reader.assert_done();
00226    }
00227 
00228 Server_Key_Exchange::~Server_Key_Exchange() {}
00229 
00230 /**
00231 * Serialize a Server Key Exchange message
00232 */
00233 std::vector<byte> Server_Key_Exchange::serialize() const
00234    {
00235    std::vector<byte> buf = params();
00236 
00237    if(m_signature.size())
00238       {
00239       // This should be an explicit version check
00240       if(m_hash_algo != "" && m_sig_algo != "")
00241          {
00242          buf.push_back(Signature_Algorithms::hash_algo_code(m_hash_algo));
00243          buf.push_back(Signature_Algorithms::sig_algo_code(m_sig_algo));
00244          }
00245 
00246       append_tls_length_value(buf, m_signature, 2);
00247       }
00248 
00249    return buf;
00250    }
00251 
00252 /**
00253 * Verify a Server Key Exchange message
00254 */
00255 bool Server_Key_Exchange::verify(const Public_Key& server_key,
00256                                  const Handshake_State& state) const
00257    {
00258    std::pair<std::string, Signature_Format> format =
00259       state.understand_sig_format(server_key, m_hash_algo, m_sig_algo);
00260 
00261    PK_Verifier verifier(server_key, format.first, format.second);
00262 
00263    verifier.update(state.client_hello()->random());
00264    verifier.update(state.server_hello()->random());
00265    verifier.update(params());
00266 
00267    return verifier.check_signature(m_signature);
00268    }
00269 
00270 const Private_Key& Server_Key_Exchange::server_kex_key() const
00271    {
00272    BOTAN_ASSERT_NONNULL(m_kex_key);
00273    return *m_kex_key;
00274    }
00275 
00276 // Only valid for SRP negotiation
00277 SRP6_Server_Session& Server_Key_Exchange::server_srp_params() const
00278    {
00279    BOTAN_ASSERT_NONNULL(m_srp_params);
00280    return *m_srp_params;
00281    }
00282 }
00283 
00284 }