Botan  1.11.15
src/lib/tls/msg_client_kex.cpp
Go to the documentation of this file.
00001 /*
00002 * Client Key Exchange Message
00003 * (C) 2004-2010 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/pubkey.h>
00014 #include <botan/dh.h>
00015 #include <botan/ecdh.h>
00016 #include <botan/rsa.h>
00017 #include <botan/srp6.h>
00018 #include <botan/rng.h>
00019 #include <botan/loadstor.h>
00020 
00021 namespace Botan {
00022 
00023 namespace TLS {
00024 
00025 namespace {
00026 
00027 secure_vector<byte> strip_leading_zeros(const secure_vector<byte>& input)
00028    {
00029    size_t leading_zeros = 0;
00030 
00031    for(size_t i = 0; i != input.size(); ++i)
00032       {
00033       if(input[i] != 0)
00034          break;
00035       ++leading_zeros;
00036       }
00037 
00038    secure_vector<byte> output(&input[leading_zeros],
00039                               &input[input.size()]);
00040    return output;
00041    }
00042 
00043 }
00044 
00045 /*
00046 * Create a new Client Key Exchange message
00047 */
00048 Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io,
00049                                          Handshake_State& state,
00050                                          const Policy& policy,
00051                                          Credentials_Manager& creds,
00052                                          const Public_Key* server_public_key,
00053                                          const std::string& hostname,
00054                                          RandomNumberGenerator& rng)
00055    {
00056    const std::string kex_algo = state.ciphersuite().kex_algo();
00057 
00058    if(kex_algo == "PSK")
00059       {
00060       std::string identity_hint = "";
00061 
00062       if(state.server_kex())
00063          {
00064          TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());
00065          identity_hint = reader.get_string(2, 0, 65535);
00066          }
00067 
00068       const std::string psk_identity = creds.psk_identity("tls-client",
00069                                                           hostname,
00070                                                           identity_hint);
00071 
00072       append_tls_length_value(m_key_material, psk_identity, 2);
00073 
00074       SymmetricKey psk = creds.psk("tls-client", hostname, psk_identity);
00075 
00076       std::vector<byte> zeros(psk.length());
00077 
00078       append_tls_length_value(m_pre_master, zeros, 2);
00079       append_tls_length_value(m_pre_master, psk.bits_of(), 2);
00080       }
00081    else if(state.server_kex())
00082       {
00083       TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());
00084 
00085       SymmetricKey psk;
00086 
00087       if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
00088          {
00089          std::string identity_hint = reader.get_string(2, 0, 65535);
00090 
00091          const std::string psk_identity = creds.psk_identity("tls-client",
00092                                                              hostname,
00093                                                              identity_hint);
00094 
00095          append_tls_length_value(m_key_material, psk_identity, 2);
00096 
00097          psk = creds.psk("tls-client", hostname, psk_identity);
00098          }
00099 
00100       if(kex_algo == "DH" || kex_algo == "DHE_PSK")
00101          {
00102          BigInt p = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
00103          BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
00104          BigInt Y = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
00105 
00106          if(reader.remaining_bytes())
00107             throw Decoding_Error("Bad params size for DH key exchange");
00108 
00109          if(p.bits() < policy.minimum_dh_group_size())
00110             throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
00111                                 "Server sent DH group of " +
00112                                 std::to_string(p.bits()) +
00113                                 " bits, policy requires at least " +
00114                                 std::to_string(policy.minimum_dh_group_size()));
00115 
00116          /*
00117          * A basic check for key validity. As we do not know q here we
00118          * cannot check that Y is in the right subgroup. However since
00119          * our key is ephemeral there does not seem to be any
00120          * advantage to bogus keys anyway.
00121          */
00122          if(Y <= 1 || Y >= p - 1)
00123             throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
00124                                 "Server sent bad DH key for DHE exchange");
00125 
00126          DL_Group group(p, g);
00127 
00128          if(!group.verify_group(rng, true))
00129             throw Internal_Error("DH group failed validation, possible attack");
00130 
00131          DH_PublicKey counterparty_key(group, Y);
00132 
00133          DH_PrivateKey priv_key(rng, group);
00134 
00135          PK_Key_Agreement ka(priv_key, "Raw");
00136 
00137          secure_vector<byte> dh_secret = strip_leading_zeros(
00138             ka.derive_key(0, counterparty_key.public_value()).bits_of());
00139 
00140          if(kex_algo == "DH")
00141             m_pre_master = dh_secret;
00142          else
00143             {
00144             append_tls_length_value(m_pre_master, dh_secret, 2);
00145             append_tls_length_value(m_pre_master, psk.bits_of(), 2);
00146             }
00147 
00148          append_tls_length_value(m_key_material, priv_key.public_value(), 2);
00149          }
00150       else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
00151          {
00152          const byte curve_type = reader.get_byte();
00153 
00154          if(curve_type != 3)
00155             throw Decoding_Error("Server sent non-named ECC curve");
00156 
00157          const u16bit curve_id = reader.get_u16bit();
00158 
00159          const std::string name = Supported_Elliptic_Curves::curve_id_to_name(curve_id);
00160 
00161          if(name == "")
00162             throw Decoding_Error("Server sent unknown named curve " + std::to_string(curve_id));
00163 
00164          EC_Group group(name);
00165 
00166          std::vector<byte> ecdh_key = reader.get_range<byte>(1, 1, 255);
00167 
00168          ECDH_PublicKey counterparty_key(group, OS2ECP(ecdh_key, group.get_curve()));
00169 
00170          ECDH_PrivateKey priv_key(rng, group);
00171 
00172          PK_Key_Agreement ka(priv_key, "Raw");
00173 
00174          secure_vector<byte> ecdh_secret =
00175             ka.derive_key(0, counterparty_key.public_value()).bits_of();
00176 
00177          if(kex_algo == "ECDH")
00178             m_pre_master = ecdh_secret;
00179          else
00180             {
00181             append_tls_length_value(m_pre_master, ecdh_secret, 2);
00182             append_tls_length_value(m_pre_master, psk.bits_of(), 2);
00183             }
00184 
00185          append_tls_length_value(m_key_material, priv_key.public_value(), 1);
00186          }
00187       else if(kex_algo == "SRP_SHA")
00188          {
00189          const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
00190          const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
00191          std::vector<byte> salt = reader.get_range<byte>(1, 1, 255);
00192          const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
00193 
00194          const std::string srp_group = srp6_group_identifier(N, g);
00195 
00196          const std::string srp_identifier =
00197             creds.srp_identifier("tls-client", hostname);
00198 
00199          const std::string srp_password =
00200             creds.srp_password("tls-client", hostname, srp_identifier);
00201 
00202          std::pair<BigInt, SymmetricKey> srp_vals =
00203             srp6_client_agree(srp_identifier,
00204                               srp_password,
00205                               srp_group,
00206                               "SHA-1",
00207                               salt,
00208                               B,
00209                               rng);
00210 
00211          append_tls_length_value(m_key_material, BigInt::encode(srp_vals.first), 2);
00212          m_pre_master = srp_vals.second.bits_of();
00213          }
00214       else
00215          {
00216          throw Internal_Error("Client_Key_Exchange: Unknown kex " +
00217                               kex_algo);
00218          }
00219 
00220       reader.assert_done();
00221       }
00222    else
00223       {
00224       // No server key exchange msg better mean RSA kex + RSA key in cert
00225 
00226       if(kex_algo != "RSA")
00227          throw Unexpected_Message("No server kex but negotiated kex " + kex_algo);
00228 
00229       if(!server_public_key)
00230          throw Internal_Error("No server public key for RSA exchange");
00231 
00232       if(auto rsa_pub = dynamic_cast<const RSA_PublicKey*>(server_public_key))
00233          {
00234          const Protocol_Version offered_version = state.client_hello()->version();
00235 
00236          m_pre_master = rng.random_vec(48);
00237          m_pre_master[0] = offered_version.major_version();
00238          m_pre_master[1] = offered_version.minor_version();
00239 
00240          PK_Encryptor_EME encryptor(*rsa_pub, "PKCS1v15");
00241 
00242          const std::vector<byte> encrypted_key = encryptor.encrypt(m_pre_master, rng);
00243 
00244          append_tls_length_value(m_key_material, encrypted_key, 2);
00245          }
00246       else
00247          throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00248                              "Expected a RSA key in server cert but got " +
00249                              server_public_key->algo_name());
00250       }
00251 
00252    state.hash().update(io.send(*this));
00253    }
00254 
00255 /*
00256 * Read a Client Key Exchange message
00257 */
00258 Client_Key_Exchange::Client_Key_Exchange(const std::vector<byte>& contents,
00259                                          const Handshake_State& state,
00260                                          const Private_Key* server_rsa_kex_key,
00261                                          Credentials_Manager& creds,
00262                                          const Policy& policy,
00263                                          RandomNumberGenerator& rng)
00264    {
00265    const std::string kex_algo = state.ciphersuite().kex_algo();
00266 
00267    if(kex_algo == "RSA")
00268       {
00269       BOTAN_ASSERT(state.server_certs() && !state.server_certs()->cert_chain().empty(),
00270                    "RSA key exchange negotiated so server sent a certificate");
00271 
00272       if(!server_rsa_kex_key)
00273          throw Internal_Error("Expected RSA kex but no server kex key set");
00274 
00275       if(!dynamic_cast<const RSA_PrivateKey*>(server_rsa_kex_key))
00276          throw Internal_Error("Expected RSA key but got " + server_rsa_kex_key->algo_name());
00277 
00278       PK_Decryptor_EME decryptor(*server_rsa_kex_key, "PKCS1v15");
00279 
00280       Protocol_Version client_version = state.client_hello()->version();
00281 
00282       /*
00283       * This is used as the pre-master if RSA decryption fails.
00284       * Otherwise we can be used as an oracle. See Bleichenbacher
00285       * "Chosen Ciphertext Attacks against Protocols Based on RSA
00286       * Encryption Standard PKCS #1", Crypto 98
00287       *
00288       * Create it here instead if in the catch clause as otherwise we
00289       * expose a timing channel WRT the generation of the fake value.
00290       * Some timing channel likely remains due to exception handling
00291       * and the like.
00292       */
00293       secure_vector<byte> fake_pre_master = rng.random_vec(48);
00294       fake_pre_master[0] = client_version.major_version();
00295       fake_pre_master[1] = client_version.minor_version();
00296 
00297       try
00298          {
00299          TLS_Data_Reader reader("ClientKeyExchange", contents);
00300          m_pre_master = decryptor.decrypt(reader.get_range<byte>(2, 0, 65535));
00301 
00302          if(m_pre_master.size() != 48 ||
00303             client_version.major_version() != m_pre_master[0] ||
00304             client_version.minor_version() != m_pre_master[1])
00305             {
00306             throw Decoding_Error("Client_Key_Exchange: Secret corrupted");
00307             }
00308          }
00309       catch(...)
00310          {
00311          m_pre_master = fake_pre_master;
00312          }
00313       }
00314    else
00315       {
00316       TLS_Data_Reader reader("ClientKeyExchange", contents);
00317 
00318       SymmetricKey psk;
00319 
00320       if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
00321          {
00322          const std::string psk_identity = reader.get_string(2, 0, 65535);
00323 
00324          psk = creds.psk("tls-server",
00325                          state.client_hello()->sni_hostname(),
00326                          psk_identity);
00327 
00328          if(psk.length() == 0)
00329             {
00330             if(policy.hide_unknown_users())
00331                psk = SymmetricKey(rng, 16);
00332             else
00333                throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY,
00334                                    "No PSK for identifier " + psk_identity);
00335             }
00336          }
00337 
00338       if(kex_algo == "PSK")
00339          {
00340          std::vector<byte> zeros(psk.length());
00341          append_tls_length_value(m_pre_master, zeros, 2);
00342          append_tls_length_value(m_pre_master, psk.bits_of(), 2);
00343          }
00344       else if(kex_algo == "SRP_SHA")
00345          {
00346          SRP6_Server_Session& srp = state.server_kex()->server_srp_params();
00347 
00348          m_pre_master = srp.step2(BigInt::decode(reader.get_range<byte>(2, 0, 65535))).bits_of();
00349          }
00350       else if(kex_algo == "DH" || kex_algo == "DHE_PSK" ||
00351               kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
00352          {
00353          const Private_Key& private_key = state.server_kex()->server_kex_key();
00354 
00355          const PK_Key_Agreement_Key* ka_key =
00356             dynamic_cast<const PK_Key_Agreement_Key*>(&private_key);
00357 
00358          if(!ka_key)
00359             throw Internal_Error("Expected key agreement key type but got " +
00360                                  private_key.algo_name());
00361 
00362          try
00363             {
00364             PK_Key_Agreement ka(*ka_key, "Raw");
00365 
00366             std::vector<byte> client_pubkey;
00367 
00368             if(ka_key->algo_name() == "DH")
00369                client_pubkey = reader.get_range<byte>(2, 0, 65535);
00370             else
00371                client_pubkey = reader.get_range<byte>(1, 0, 255);
00372 
00373             secure_vector<byte> shared_secret = ka.derive_key(0, client_pubkey).bits_of();
00374 
00375             if(ka_key->algo_name() == "DH")
00376                shared_secret = strip_leading_zeros(shared_secret);
00377 
00378             if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
00379                {
00380                append_tls_length_value(m_pre_master, shared_secret, 2);
00381                append_tls_length_value(m_pre_master, psk.bits_of(), 2);
00382                }
00383             else
00384                m_pre_master = shared_secret;
00385             }
00386          catch(std::exception &e)
00387             {
00388             /*
00389             * Something failed in the DH computation. To avoid possible
00390             * timing attacks, randomize the pre-master output and carry
00391             * on, allowing the protocol to fail later in the finished
00392             * checks.
00393             */
00394             m_pre_master = rng.random_vec(ka_key->public_value().size());
00395             }
00396          }
00397       else
00398          throw Internal_Error("Client_Key_Exchange: Unknown kex type " + kex_algo);
00399       }
00400    }
00401 
00402 }
00403 
00404 }