Botan  1.11.15
src/lib/tls/tls_client.cpp
Go to the documentation of this file.
00001 /*
00002 * TLS Client
00003 * (C) 2004-2011,2012 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/tls_client.h>
00009 #include <botan/internal/tls_handshake_state.h>
00010 #include <botan/internal/tls_messages.h>
00011 #include <botan/internal/stl_util.h>
00012 #include <iterator>
00013 #include <sstream>
00014 
00015 namespace Botan {
00016 
00017 namespace TLS {
00018 
00019 namespace {
00020 
00021 class Client_Handshake_State : public Handshake_State
00022    {
00023    public:
00024       // using Handshake_State::Handshake_State;
00025 
00026       Client_Handshake_State(Handshake_IO* io, hs_msg_cb cb = hs_msg_cb()) :
00027          Handshake_State(io, cb) {}
00028 
00029       const Public_Key& get_server_public_Key() const
00030          {
00031          BOTAN_ASSERT(server_public_key, "Server sent us a certificate");
00032          return *server_public_key.get();
00033          }
00034 
00035       // Used during session resumption
00036       secure_vector<byte> resume_master_secret;
00037 
00038       std::unique_ptr<Public_Key> server_public_key;
00039 
00040       // Used by client using NPN
00041       Client::next_protocol_fn client_npn_cb;
00042    };
00043 
00044 }
00045 
00046 /*
00047 * TLS Client Constructor
00048 */
00049 Client::Client(output_fn output_fn,
00050                data_cb proc_cb,
00051                alert_cb alert_cb,
00052                handshake_cb handshake_cb,
00053                Session_Manager& session_manager,
00054                Credentials_Manager& creds,
00055                const Policy& policy,
00056                RandomNumberGenerator& rng,
00057                const Server_Information& info,
00058                const Protocol_Version offer_version,
00059                next_protocol_fn npn,
00060                size_t io_buf_sz) :
00061    Channel(output_fn, proc_cb, alert_cb, handshake_cb, session_manager, rng,
00062            offer_version.is_datagram_protocol(), io_buf_sz),
00063    m_policy(policy),
00064    m_creds(creds),
00065    m_info(info)
00066    {
00067    const std::string srp_identifier = m_creds.srp_identifier("tls-client", m_info.hostname());
00068 
00069    Handshake_State& state = create_handshake_state(offer_version);
00070    send_client_hello(state, false, offer_version, srp_identifier, npn);
00071    }
00072 
00073 Handshake_State* Client::new_handshake_state(Handshake_IO* io)
00074    {
00075    return new Client_Handshake_State(io); // , m_hs_msg_cb);
00076    }
00077 
00078 std::vector<X509_Certificate>
00079 Client::get_peer_cert_chain(const Handshake_State& state) const
00080    {
00081    if(state.server_certs())
00082       return state.server_certs()->cert_chain();
00083    return std::vector<X509_Certificate>();
00084    }
00085 
00086 /*
00087 * Send a new client hello to renegotiate
00088 */
00089 void Client::initiate_handshake(Handshake_State& state,
00090                                 bool force_full_renegotiation)
00091    {
00092    send_client_hello(state,
00093                      force_full_renegotiation,
00094                      state.version());
00095    }
00096 
00097 void Client::send_client_hello(Handshake_State& state_base,
00098                                bool force_full_renegotiation,
00099                                Protocol_Version version,
00100                                const std::string& srp_identifier,
00101                                next_protocol_fn next_protocol)
00102    {
00103    Client_Handshake_State& state = dynamic_cast<Client_Handshake_State&>(state_base);
00104 
00105    if(state.version().is_datagram_protocol())
00106       state.set_expected_next(HELLO_VERIFY_REQUEST); // optional
00107    state.set_expected_next(SERVER_HELLO);
00108 
00109    state.client_npn_cb = next_protocol;
00110 
00111    const bool send_npn_request = static_cast<bool>(next_protocol);
00112 
00113    if(!force_full_renegotiation && !m_info.empty())
00114       {
00115       Session session_info;
00116       if(session_manager().load_from_server_info(m_info, session_info))
00117          {
00118          if(srp_identifier == "" || session_info.srp_identifier() == srp_identifier)
00119             {
00120             state.client_hello(new Client_Hello(
00121                state.handshake_io(),
00122                state.hash(),
00123                m_policy,
00124                rng(),
00125                secure_renegotiation_data_for_client_hello(),
00126                session_info,
00127                send_npn_request));
00128 
00129             state.resume_master_secret = session_info.master_secret();
00130             }
00131          }
00132       }
00133 
00134    if(!state.client_hello()) // not resuming
00135       {
00136       state.client_hello(new Client_Hello(
00137          state.handshake_io(),
00138          state.hash(),
00139          version,
00140          m_policy,
00141          rng(),
00142          secure_renegotiation_data_for_client_hello(),
00143          send_npn_request,
00144          m_info.hostname(),
00145          srp_identifier));
00146       }
00147 
00148    secure_renegotiation_check(state.client_hello());
00149    }
00150 
00151 /*
00152 * Process a handshake message
00153 */
00154 void Client::process_handshake_msg(const Handshake_State* active_state,
00155                                    Handshake_State& state_base,
00156                                    Handshake_Type type,
00157                                    const std::vector<byte>& contents)
00158    {
00159    Client_Handshake_State& state = dynamic_cast<Client_Handshake_State&>(state_base);
00160 
00161    if(type == HELLO_REQUEST && active_state)
00162       {
00163       Hello_Request hello_request(contents);
00164 
00165       // Ignore request entirely if we are currently negotiating a handshake
00166       if(state.client_hello())
00167          return;
00168 
00169       if(m_policy.allow_server_initiated_renegotiation())
00170          {
00171          if(!secure_renegotiation_supported() && m_policy.allow_insecure_renegotiation() == false)
00172             send_warning_alert(Alert::NO_RENEGOTIATION);
00173          else
00174             this->initiate_handshake(state, false);
00175          }
00176       else
00177          {
00178          // RFC 5746 section 4.2
00179          send_warning_alert(Alert::NO_RENEGOTIATION);
00180          }
00181 
00182       return;
00183       }
00184 
00185    state.confirm_transition_to(type);
00186 
00187    if(type != HANDSHAKE_CCS && type != FINISHED && type != HELLO_VERIFY_REQUEST)
00188       state.hash().update(state.handshake_io().format(contents, type));
00189 
00190    if(type == HELLO_VERIFY_REQUEST)
00191       {
00192       state.set_expected_next(SERVER_HELLO);
00193       state.set_expected_next(HELLO_VERIFY_REQUEST); // might get it again
00194 
00195       Hello_Verify_Request hello_verify_request(contents);
00196 
00197       state.hello_verify_request(hello_verify_request);
00198       }
00199    else if(type == SERVER_HELLO)
00200       {
00201       state.server_hello(new Server_Hello(contents));
00202 
00203       if(!state.client_hello()->offered_suite(state.server_hello()->ciphersuite()))
00204          {
00205          throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00206                              "Server replied with ciphersuite we didn't send");
00207          }
00208 
00209       if(Ciphersuite::is_scsv(state.server_hello()->ciphersuite()))
00210          {
00211          throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00212                              "Server replied with a signaling ciphersuite");
00213          }
00214 
00215       if(!value_exists(state.client_hello()->compression_methods(),
00216                        state.server_hello()->compression_method()))
00217          {
00218          throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00219                              "Server replied with compression method we didn't send");
00220          }
00221 
00222       auto client_extn = state.client_hello()->extension_types();
00223       auto server_extn = state.server_hello()->extension_types();
00224 
00225       std::vector<Handshake_Extension_Type> diff;
00226 
00227       std::set_difference(server_extn.begin(), server_extn.end(),
00228                           client_extn.begin(), server_extn.end(),
00229                           std::back_inserter(diff));
00230 
00231       if(!diff.empty())
00232          {
00233          // Server sent us back an extension we did not send!
00234 
00235          std::ostringstream msg;
00236          msg << "Server replied with " << diff.size() << " unsupported extensions:";
00237          for(auto&& d : diff)
00238             msg << " " << static_cast<int>(d);
00239          throw TLS_Exception(Alert::HANDSHAKE_FAILURE, msg.str());
00240          }
00241 
00242       if(u16bit srtp = state.server_hello()->srtp_profile())
00243          {
00244          if(!value_exists(state.client_hello()->srtp_profiles(), srtp))
00245             throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00246                                 "Server replied with DTLS-SRTP alg we did not send");
00247          }
00248 
00249       state.set_version(state.server_hello()->version());
00250 
00251       secure_renegotiation_check(state.server_hello());
00252 
00253       const bool server_returned_same_session_id =
00254          !state.server_hello()->session_id().empty() &&
00255          (state.server_hello()->session_id() == state.client_hello()->session_id());
00256 
00257       if(server_returned_same_session_id)
00258          {
00259          // successful resumption
00260 
00261          /*
00262          * In this case, we offered the version used in the original
00263          * session, and the server must resume with the same version.
00264          */
00265          if(state.server_hello()->version() != state.client_hello()->version())
00266             throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00267                                 "Server resumed session but with wrong version");
00268 
00269          state.compute_session_keys(state.resume_master_secret);
00270 
00271          if(state.server_hello()->supports_session_ticket())
00272             state.set_expected_next(NEW_SESSION_TICKET);
00273          else
00274             state.set_expected_next(HANDSHAKE_CCS);
00275          }
00276       else
00277          {
00278          // new session
00279 
00280          if(state.client_hello()->version().is_datagram_protocol() !=
00281             state.server_hello()->version().is_datagram_protocol())
00282             {
00283             throw TLS_Exception(Alert::PROTOCOL_VERSION,
00284                                 "Server replied with different protocol type than we offered");
00285             }
00286 
00287          if(state.version() > state.client_hello()->version())
00288             {
00289             throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00290                                 "Server replied with later version than in hello");
00291             }
00292 
00293          if(!m_policy.acceptable_protocol_version(state.version()))
00294             {
00295             throw TLS_Exception(Alert::PROTOCOL_VERSION,
00296                                 "Server version " + state.version().to_string() +
00297                                 " is unacceptable by policy");
00298             }
00299 
00300          if(state.ciphersuite().sig_algo() != "")
00301             {
00302             state.set_expected_next(CERTIFICATE);
00303             }
00304          else if(state.ciphersuite().kex_algo() == "PSK")
00305             {
00306             /* PSK is anonymous so no certificate/cert req message is
00307                ever sent. The server may or may not send a server kex,
00308                depending on if it has an identity hint for us.
00309 
00310                (EC)DHE_PSK always sends a server key exchange for the
00311                DH exchange portion.
00312             */
00313 
00314             state.set_expected_next(SERVER_KEX);
00315             state.set_expected_next(SERVER_HELLO_DONE);
00316             }
00317          else if(state.ciphersuite().kex_algo() != "RSA")
00318             {
00319             state.set_expected_next(SERVER_KEX);
00320             }
00321          else
00322             {
00323             state.set_expected_next(CERTIFICATE_REQUEST); // optional
00324             state.set_expected_next(SERVER_HELLO_DONE);
00325             }
00326          }
00327       }
00328    else if(type == CERTIFICATE)
00329       {
00330       if(state.ciphersuite().kex_algo() != "RSA")
00331          {
00332          state.set_expected_next(SERVER_KEX);
00333          }
00334       else
00335          {
00336          state.set_expected_next(CERTIFICATE_REQUEST); // optional
00337          state.set_expected_next(SERVER_HELLO_DONE);
00338          }
00339 
00340       state.server_certs(new Certificate(contents));
00341 
00342       const std::vector<X509_Certificate>& server_certs =
00343          state.server_certs()->cert_chain();
00344 
00345       if(server_certs.empty())
00346          throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00347                              "Client: No certificates sent by server");
00348 
00349       try
00350          {
00351          m_creds.verify_certificate_chain("tls-client", m_info.hostname(), server_certs);
00352          }
00353       catch(std::exception& e)
00354          {
00355          throw TLS_Exception(Alert::BAD_CERTIFICATE, e.what());
00356          }
00357 
00358       std::unique_ptr<Public_Key> peer_key(server_certs[0].subject_public_key());
00359 
00360       if(peer_key->algo_name() != state.ciphersuite().sig_algo())
00361          throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
00362                              "Certificate key type did not match ciphersuite");
00363 
00364       state.server_public_key.reset(peer_key.release());
00365       }
00366    else if(type == SERVER_KEX)
00367       {
00368       state.set_expected_next(CERTIFICATE_REQUEST); // optional
00369       state.set_expected_next(SERVER_HELLO_DONE);
00370 
00371       state.server_kex(
00372          new Server_Key_Exchange(contents,
00373                                  state.ciphersuite().kex_algo(),
00374                                  state.ciphersuite().sig_algo(),
00375                                  state.version())
00376          );
00377 
00378       if(state.ciphersuite().sig_algo() != "")
00379          {
00380          const Public_Key& server_key = state.get_server_public_Key();
00381 
00382          if(!state.server_kex()->verify(server_key, state))
00383             {
00384             throw TLS_Exception(Alert::DECRYPT_ERROR,
00385                                 "Bad signature on server key exchange");
00386             }
00387          }
00388       }
00389    else if(type == CERTIFICATE_REQUEST)
00390       {
00391       state.set_expected_next(SERVER_HELLO_DONE);
00392       state.cert_req(
00393          new Certificate_Req(contents, state.version())
00394          );
00395       }
00396    else if(type == SERVER_HELLO_DONE)
00397       {
00398       state.server_hello_done(
00399          new Server_Hello_Done(contents)
00400          );
00401 
00402       if(state.received_handshake_msg(CERTIFICATE_REQUEST))
00403          {
00404          const std::vector<std::string>& types =
00405             state.cert_req()->acceptable_cert_types();
00406 
00407          std::vector<X509_Certificate> client_certs =
00408             m_creds.cert_chain(types,
00409                                "tls-client",
00410                                m_info.hostname());
00411 
00412          state.client_certs(
00413             new Certificate(state.handshake_io(),
00414                             state.hash(),
00415                             client_certs)
00416             );
00417          }
00418 
00419       state.client_kex(
00420          new Client_Key_Exchange(state.handshake_io(),
00421                                  state,
00422                                  m_policy,
00423                                  m_creds,
00424                                  state.server_public_key.get(),
00425                                  m_info.hostname(),
00426                                  rng())
00427          );
00428 
00429       state.compute_session_keys();
00430 
00431       if(state.received_handshake_msg(CERTIFICATE_REQUEST) &&
00432          !state.client_certs()->empty())
00433          {
00434          Private_Key* private_key =
00435             m_creds.private_key_for(state.client_certs()->cert_chain()[0],
00436                                     "tls-client",
00437                                     m_info.hostname());
00438 
00439          state.client_verify(
00440             new Certificate_Verify(state.handshake_io(),
00441                                    state,
00442                                    m_policy,
00443                                    rng(),
00444                                    private_key)
00445             );
00446          }
00447 
00448       state.handshake_io().send(Change_Cipher_Spec());
00449 
00450       change_cipher_spec_writer(CLIENT);
00451 
00452       if(state.server_hello()->next_protocol_notification())
00453          {
00454          const std::string protocol = state.client_npn_cb(
00455             state.server_hello()->next_protocols());
00456 
00457          state.next_protocol(
00458             new Next_Protocol(state.handshake_io(), state.hash(), protocol)
00459             );
00460          }
00461 
00462       state.client_finished(
00463          new Finished(state.handshake_io(), state, CLIENT)
00464          );
00465 
00466       if(state.server_hello()->supports_session_ticket())
00467          state.set_expected_next(NEW_SESSION_TICKET);
00468       else
00469          state.set_expected_next(HANDSHAKE_CCS);
00470       }
00471    else if(type == NEW_SESSION_TICKET)
00472       {
00473       state.new_session_ticket(new New_Session_Ticket(contents));
00474 
00475       state.set_expected_next(HANDSHAKE_CCS);
00476       }
00477    else if(type == HANDSHAKE_CCS)
00478       {
00479       state.set_expected_next(FINISHED);
00480 
00481       change_cipher_spec_reader(CLIENT);
00482       }
00483    else if(type == FINISHED)
00484       {
00485       state.server_finished(new Finished(contents));
00486 
00487       if(!state.server_finished()->verify(state, SERVER))
00488          throw TLS_Exception(Alert::DECRYPT_ERROR,
00489                              "Finished message didn't verify");
00490 
00491       state.hash().update(state.handshake_io().format(contents, type));
00492 
00493       if(!state.client_finished()) // session resume case
00494          {
00495          state.handshake_io().send(Change_Cipher_Spec());
00496 
00497          change_cipher_spec_writer(CLIENT);
00498 
00499          if(state.server_hello()->next_protocol_notification())
00500             {
00501             const std::string protocol = state.client_npn_cb(
00502                   state.server_hello()->next_protocols());
00503 
00504             state.next_protocol(
00505                new Next_Protocol(state.handshake_io(), state.hash(), protocol)
00506                );
00507             }
00508 
00509          state.client_finished(
00510             new Finished(state.handshake_io(), state, CLIENT)
00511             );
00512          }
00513 
00514       std::vector<byte> session_id = state.server_hello()->session_id();
00515 
00516       const std::vector<byte>& session_ticket = state.session_ticket();
00517 
00518       if(session_id.empty() && !session_ticket.empty())
00519          session_id = make_hello_random(rng(), m_policy);
00520 
00521       Session session_info(
00522          session_id,
00523          state.session_keys().master_secret(),
00524          state.server_hello()->version(),
00525          state.server_hello()->ciphersuite(),
00526          state.server_hello()->compression_method(),
00527          CLIENT,
00528          state.server_hello()->fragment_size(),
00529          get_peer_cert_chain(state),
00530          session_ticket,
00531          m_info,
00532          "",
00533          state.server_hello()->srtp_profile()
00534          );
00535 
00536       const bool should_save = save_session(session_info);
00537 
00538       if(!session_id.empty())
00539          {
00540          if(should_save)
00541             session_manager().save(session_info);
00542          else
00543             session_manager().remove_entry(session_info.session_id());
00544          }
00545 
00546       activate_session();
00547       }
00548    else
00549       throw Unexpected_Message("Unknown handshake message received");
00550    }
00551 
00552 }
00553 
00554 }