Botan  1.11.15
src/lib/tls/tls_server.cpp
Go to the documentation of this file.
00001 /*
00002 * TLS Server
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_server.h>
00009 #include <botan/internal/tls_handshake_state.h>
00010 #include <botan/internal/tls_messages.h>
00011 #include <botan/internal/stl_util.h>
00012 
00013 namespace Botan {
00014 
00015 namespace TLS {
00016 
00017 namespace {
00018 
00019 class Server_Handshake_State : public Handshake_State
00020    {
00021    public:
00022       // using Handshake_State::Handshake_State;
00023 
00024       Server_Handshake_State(Handshake_IO* io, hs_msg_cb cb = hs_msg_cb()) :
00025          Handshake_State(io, cb) {}
00026 
00027       // Used by the server only, in case of RSA key exchange. Not owned
00028       Private_Key* server_rsa_kex_key = nullptr;
00029 
00030       /*
00031       * Used by the server to know if resumption should be allowed on
00032       * a server-initiated renegotiation
00033       */
00034       bool allow_session_resumption = true;
00035    };
00036 
00037 bool check_for_resume(Session& session_info,
00038                       Session_Manager& session_manager,
00039                       Credentials_Manager& credentials,
00040                       const Client_Hello* client_hello,
00041                       std::chrono::seconds session_ticket_lifetime)
00042    {
00043    const std::vector<byte>& client_session_id = client_hello->session_id();
00044    const std::vector<byte>& session_ticket = client_hello->session_ticket();
00045 
00046    if(session_ticket.empty())
00047       {
00048       if(client_session_id.empty()) // not resuming
00049          return false;
00050 
00051       // not found
00052       if(!session_manager.load_from_session_id(client_session_id, session_info))
00053          return false;
00054       }
00055    else
00056       {
00057       // If a session ticket was sent, ignore client session ID
00058       try
00059          {
00060          session_info = Session::decrypt(
00061             session_ticket,
00062             credentials.psk("tls-server", "session-ticket", ""));
00063 
00064          if(session_ticket_lifetime != std::chrono::seconds(0) &&
00065             session_info.session_age() > session_ticket_lifetime)
00066             return false; // ticket has expired
00067          }
00068       catch(...)
00069          {
00070          return false;
00071          }
00072       }
00073 
00074    // wrong version
00075    if(client_hello->version() != session_info.version())
00076       return false;
00077 
00078    // client didn't send original ciphersuite
00079    if(!value_exists(client_hello->ciphersuites(),
00080                     session_info.ciphersuite_code()))
00081       return false;
00082 
00083    // client didn't send original compression method
00084    if(!value_exists(client_hello->compression_methods(),
00085                     session_info.compression_method()))
00086       return false;
00087 
00088    // client sent a different SRP identity
00089    if(client_hello->srp_identifier() != "")
00090       {
00091       if(client_hello->srp_identifier() != session_info.srp_identifier())
00092          return false;
00093       }
00094 
00095    // client sent a different SNI hostname
00096    if(client_hello->sni_hostname() != "")
00097       {
00098       if(client_hello->sni_hostname() != session_info.server_info().hostname())
00099          return false;
00100       }
00101 
00102    return true;
00103    }
00104 
00105 /*
00106 * Choose which ciphersuite to use
00107 */
00108 u16bit choose_ciphersuite(
00109    const Policy& policy,
00110    Protocol_Version version,
00111    Credentials_Manager& creds,
00112    const std::map<std::string, std::vector<X509_Certificate> >& cert_chains,
00113    const Client_Hello* client_hello)
00114    {
00115    const bool our_choice = policy.server_uses_own_ciphersuite_preferences();
00116    const bool have_srp = creds.attempt_srp("tls-server", client_hello->sni_hostname());
00117    const std::vector<u16bit> client_suites = client_hello->ciphersuites();
00118    const std::vector<u16bit> server_suites = policy.ciphersuite_list(version, have_srp);
00119 
00120    if(server_suites.empty())
00121       throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00122                           "Policy forbids us from negotiating any ciphersuite");
00123 
00124    const bool have_shared_ecc_curve =
00125       (policy.choose_curve(client_hello->supported_ecc_curves()) != "");
00126 
00127    std::vector<u16bit> pref_list = server_suites;
00128    std::vector<u16bit> other_list = client_suites;
00129 
00130    if(!our_choice)
00131       std::swap(pref_list, other_list);
00132 
00133    for(auto suite_id : pref_list)
00134       {
00135       if(!value_exists(other_list, suite_id))
00136          continue;
00137 
00138       Ciphersuite suite = Ciphersuite::by_id(suite_id);
00139 
00140       if(!have_shared_ecc_curve && suite.ecc_ciphersuite())
00141          continue;
00142 
00143       if(suite.sig_algo() != "" && cert_chains.count(suite.sig_algo()) == 0)
00144          continue;
00145 
00146       /*
00147       The client may offer SRP cipher suites in the hello message but
00148       omit the SRP extension.  If the server would like to select an
00149       SRP cipher suite in this case, the server SHOULD return a fatal
00150       "unknown_psk_identity" alert immediately after processing the
00151       client hello message.
00152        - RFC 5054 section 2.5.1.2
00153       */
00154       if(suite.kex_algo() == "SRP_SHA" && client_hello->srp_identifier() == "")
00155          throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY,
00156                              "Client wanted SRP but did not send username");
00157 
00158       return suite_id;
00159       }
00160 
00161    throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00162                        "Can't agree on a ciphersuite with client");
00163    }
00164 
00165 
00166 /*
00167 * Choose which compression algorithm to use
00168 */
00169 byte choose_compression(const Policy& policy,
00170                         const std::vector<byte>& c_comp)
00171    {
00172    std::vector<byte> s_comp = policy.compression();
00173 
00174    for(size_t i = 0; i != s_comp.size(); ++i)
00175       for(size_t j = 0; j != c_comp.size(); ++j)
00176          if(s_comp[i] == c_comp[j])
00177             return s_comp[i];
00178 
00179    return NO_COMPRESSION;
00180    }
00181 
00182 std::map<std::string, std::vector<X509_Certificate> >
00183 get_server_certs(const std::string& hostname,
00184                  Credentials_Manager& creds)
00185    {
00186    const char* cert_types[] = { "RSA", "DSA", "ECDSA", nullptr };
00187 
00188    std::map<std::string, std::vector<X509_Certificate> > cert_chains;
00189 
00190    for(size_t i = 0; cert_types[i]; ++i)
00191       {
00192       std::vector<X509_Certificate> certs =
00193          creds.cert_chain_single_type(cert_types[i], "tls-server", hostname);
00194 
00195       if(!certs.empty())
00196          cert_chains[cert_types[i]] = certs;
00197       }
00198 
00199    return cert_chains;
00200    }
00201 
00202 }
00203 
00204 /*
00205 * TLS Server Constructor
00206 */
00207 Server::Server(output_fn output,
00208                data_cb data_cb,
00209                alert_cb alert_cb,
00210                handshake_cb handshake_cb,
00211                Session_Manager& session_manager,
00212                Credentials_Manager& creds,
00213                const Policy& policy,
00214                RandomNumberGenerator& rng,
00215                const std::vector<std::string>& next_protocols,
00216                bool is_datagram,
00217                size_t io_buf_sz) :
00218    Channel(output, data_cb, alert_cb, handshake_cb,
00219            session_manager, rng, is_datagram, io_buf_sz),
00220    m_policy(policy),
00221    m_creds(creds),
00222    m_possible_protocols(next_protocols)
00223    {
00224    }
00225 
00226 Handshake_State* Server::new_handshake_state(Handshake_IO* io)
00227    {
00228    std::unique_ptr<Handshake_State> state(new Server_Handshake_State(io));
00229    state->set_expected_next(CLIENT_HELLO);
00230    return state.release();
00231    }
00232 
00233 std::vector<X509_Certificate>
00234 Server::get_peer_cert_chain(const Handshake_State& state) const
00235    {
00236    if(state.client_certs())
00237       return state.client_certs()->cert_chain();
00238    return std::vector<X509_Certificate>();
00239    }
00240 
00241 /*
00242 * Send a hello request to the client
00243 */
00244 void Server::initiate_handshake(Handshake_State& state,
00245                                 bool force_full_renegotiation)
00246    {
00247    dynamic_cast<Server_Handshake_State&>(state).allow_session_resumption =
00248       !force_full_renegotiation;
00249 
00250    Hello_Request hello_req(state.handshake_io());
00251    }
00252 
00253 /*
00254 * Process a handshake message
00255 */
00256 void Server::process_handshake_msg(const Handshake_State* active_state,
00257                                    Handshake_State& state_base,
00258                                    Handshake_Type type,
00259                                    const std::vector<byte>& contents)
00260    {
00261    Server_Handshake_State& state = dynamic_cast<Server_Handshake_State&>(state_base);
00262 
00263    state.confirm_transition_to(type);
00264 
00265    /*
00266    * The change cipher spec message isn't technically a handshake
00267    * message so it's not included in the hash. The finished and
00268    * certificate verify messages are verified based on the current
00269    * state of the hash *before* this message so we delay adding them
00270    * to the hash computation until we've processed them below.
00271    */
00272    if(type != HANDSHAKE_CCS && type != FINISHED && type != CERTIFICATE_VERIFY)
00273       {
00274       state.hash().update(state.handshake_io().format(contents, type));
00275       }
00276 
00277    if(type == CLIENT_HELLO)
00278       {
00279       const bool initial_handshake = !active_state;
00280 
00281       if(!m_policy.allow_insecure_renegotiation() &&
00282          !(initial_handshake || secure_renegotiation_supported()))
00283          {
00284          send_warning_alert(Alert::NO_RENEGOTIATION);
00285          return;
00286          }
00287 
00288       state.client_hello(new Client_Hello(contents));
00289 
00290       const Protocol_Version client_version = state.client_hello()->version();
00291 
00292       Protocol_Version negotiated_version;
00293 
00294       const Protocol_Version latest_supported =
00295          m_policy.latest_supported_version(client_version.is_datagram_protocol());
00296 
00297       if((initial_handshake && client_version.known_version()) ||
00298          (!initial_handshake && client_version == active_state->version()))
00299          {
00300          /*
00301          Common cases: new client hello with some known version, or a
00302          renegotiation using the same version as previously
00303          negotiated.
00304          */
00305 
00306          negotiated_version = client_version;
00307          }
00308       else if(!initial_handshake && (client_version != active_state->version()))
00309          {
00310          /*
00311          * If this is a renegotiation, and the client has offered a
00312          * later version than what it initially negotiated, negotiate
00313          * the old version. This matches OpenSSL's behavior. If the
00314          * client is offering a version earlier than what it initially
00315          * negotiated, reject as a probable attack.
00316          */
00317          if(active_state->version() > client_version)
00318             {
00319             throw TLS_Exception(Alert::PROTOCOL_VERSION,
00320                                 "Client negotiated " +
00321                                 active_state->version().to_string() +
00322                                 " then renegotiated with " +
00323                                 client_version.to_string());
00324             }
00325          else
00326             negotiated_version = active_state->version();
00327          }
00328       else
00329          {
00330          /*
00331          New negotiation using a version we don't know. Offer them the
00332          best we currently know and support
00333          */
00334          negotiated_version = latest_supported;
00335          }
00336 
00337       if(!m_policy.acceptable_protocol_version(negotiated_version))
00338          {
00339          throw TLS_Exception(Alert::PROTOCOL_VERSION,
00340                              "Client version " + negotiated_version.to_string() +
00341                              " is unacceptable by policy");
00342          }
00343 
00344       if(state.client_hello()->sent_fallback_scsv())
00345          {
00346          if(latest_supported > client_version)
00347             throw TLS_Exception(Alert::INAPPROPRIATE_FALLBACK,
00348                                 "Client signalled fallback SCSV, possible attack");
00349          }
00350 
00351       if(!initial_handshake && state.client_hello()->next_protocol_notification())
00352          throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
00353                              "Client included NPN extension for renegotiation");
00354 
00355       secure_renegotiation_check(state.client_hello());
00356 
00357       state.set_version(negotiated_version);
00358 
00359       Session session_info;
00360       const bool resuming =
00361          state.allow_session_resumption &&
00362          check_for_resume(session_info,
00363                           session_manager(),
00364                           m_creds,
00365                           state.client_hello(),
00366                           std::chrono::seconds(m_policy.session_ticket_lifetime()));
00367 
00368       bool have_session_ticket_key = false;
00369 
00370       try
00371          {
00372          have_session_ticket_key =
00373             m_creds.psk("tls-server", "session-ticket", "").length() > 0;
00374          }
00375       catch(...) {}
00376 
00377       if(resuming)
00378          {
00379          // Only offer a resuming client a new ticket if they didn't send one this time,
00380          // ie, resumed via server-side resumption. TODO: also send one if expiring soon?
00381 
00382          const bool offer_new_session_ticket =
00383             (state.client_hello()->supports_session_ticket() &&
00384              state.client_hello()->session_ticket().empty() &&
00385              have_session_ticket_key);
00386 
00387          state.server_hello(new Server_Hello(
00388                state.handshake_io(),
00389                state.hash(),
00390                m_policy,
00391                rng(),
00392                secure_renegotiation_data_for_server_hello(),
00393                *state.client_hello(),
00394                session_info,
00395                offer_new_session_ticket,
00396                m_possible_protocols
00397             ));
00398 
00399          secure_renegotiation_check(state.server_hello());
00400 
00401          state.compute_session_keys(session_info.master_secret());
00402 
00403          if(!save_session(session_info))
00404             {
00405             session_manager().remove_entry(session_info.session_id());
00406 
00407             if(state.server_hello()->supports_session_ticket()) // send an empty ticket
00408                {
00409                state.new_session_ticket(
00410                   new New_Session_Ticket(state.handshake_io(),
00411                                          state.hash())
00412                   );
00413                }
00414             }
00415 
00416          if(state.server_hello()->supports_session_ticket() && !state.new_session_ticket())
00417             {
00418             try
00419                {
00420                const SymmetricKey ticket_key = m_creds.psk("tls-server", "session-ticket", "");
00421 
00422                state.new_session_ticket(
00423                   new New_Session_Ticket(state.handshake_io(),
00424                                          state.hash(),
00425                                          session_info.encrypt(ticket_key, rng()),
00426                                          m_policy.session_ticket_lifetime())
00427                   );
00428                }
00429             catch(...) {}
00430 
00431             if(!state.new_session_ticket())
00432                {
00433                state.new_session_ticket(
00434                   new New_Session_Ticket(state.handshake_io(), state.hash())
00435                   );
00436                }
00437             }
00438 
00439          state.handshake_io().send(Change_Cipher_Spec());
00440 
00441          change_cipher_spec_writer(SERVER);
00442 
00443          state.server_finished(
00444             new Finished(state.handshake_io(), state, SERVER)
00445             );
00446 
00447          state.set_expected_next(HANDSHAKE_CCS);
00448          }
00449       else // new session
00450          {
00451          std::map<std::string, std::vector<X509_Certificate> > cert_chains;
00452 
00453          const std::string sni_hostname = state.client_hello()->sni_hostname();
00454 
00455          cert_chains = get_server_certs(sni_hostname, m_creds);
00456 
00457          if(sni_hostname != "" && cert_chains.empty())
00458             {
00459             cert_chains = get_server_certs("", m_creds);
00460 
00461             /*
00462             * Only send the unrecognized_name alert if we couldn't
00463             * find any certs for the requested name but did find at
00464             * least one cert to use in general. That avoids sending an
00465             * unrecognized_name when a server is configured for purely
00466             * anonymous operation.
00467             */
00468             if(!cert_chains.empty())
00469                send_alert(Alert(Alert::UNRECOGNIZED_NAME));
00470             }
00471 
00472          state.server_hello(new Server_Hello(
00473                state.handshake_io(),
00474                state.hash(),
00475                m_policy,
00476                rng(),
00477                secure_renegotiation_data_for_server_hello(),
00478                *state.client_hello(),
00479                make_hello_random(rng(), m_policy), // new session ID
00480                state.version(),
00481                choose_ciphersuite(m_policy, state.version(), m_creds, cert_chains, state.client_hello()),
00482                choose_compression(m_policy, state.client_hello()->compression_methods()),
00483                have_session_ticket_key,
00484                m_possible_protocols)
00485             );
00486 
00487          secure_renegotiation_check(state.server_hello());
00488 
00489          const std::string sig_algo = state.ciphersuite().sig_algo();
00490          const std::string kex_algo = state.ciphersuite().kex_algo();
00491 
00492          if(sig_algo != "")
00493             {
00494             BOTAN_ASSERT(!cert_chains[sig_algo].empty(),
00495                          "Attempting to send empty certificate chain");
00496 
00497             state.server_certs(
00498                new Certificate(state.handshake_io(),
00499                                state.hash(),
00500                                cert_chains[sig_algo])
00501                );
00502             }
00503 
00504          Private_Key* private_key = nullptr;
00505 
00506          if(kex_algo == "RSA" || sig_algo != "")
00507             {
00508             private_key = m_creds.private_key_for(
00509                state.server_certs()->cert_chain()[0],
00510                "tls-server",
00511                sni_hostname);
00512 
00513             if(!private_key)
00514                throw Internal_Error("No private key located for associated server cert");
00515             }
00516 
00517          if(kex_algo == "RSA")
00518             {
00519             state.server_rsa_kex_key = private_key;
00520             }
00521          else
00522             {
00523             state.server_kex(new Server_Key_Exchange(state.handshake_io(),
00524                                                      state, m_policy,
00525                                                      m_creds, rng(), private_key));
00526             }
00527 
00528          auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-server", sni_hostname);
00529 
00530          std::vector<X509_DN> client_auth_CAs;
00531 
00532          for(auto store : trusted_CAs)
00533             {
00534             auto subjects = store->all_subjects();
00535             client_auth_CAs.insert(client_auth_CAs.end(), subjects.begin(), subjects.end());
00536             }
00537 
00538          if(!client_auth_CAs.empty() && state.ciphersuite().sig_algo() != "")
00539             {
00540             state.cert_req(
00541                new Certificate_Req(state.handshake_io(),
00542                                    state.hash(),
00543                                    m_policy,
00544                                    client_auth_CAs,
00545                                    state.version())
00546                );
00547 
00548             state.set_expected_next(CERTIFICATE);
00549             }
00550 
00551          /*
00552          * If the client doesn't have a cert they want to use they are
00553          * allowed to send either an empty cert message or proceed
00554          * directly to the client key exchange, so allow either case.
00555          */
00556          state.set_expected_next(CLIENT_KEX);
00557 
00558          state.server_hello_done(
00559             new Server_Hello_Done(state.handshake_io(), state.hash())
00560             );
00561          }
00562       }
00563    else if(type == CERTIFICATE)
00564       {
00565       state.client_certs(new Certificate(contents));
00566 
00567       state.set_expected_next(CLIENT_KEX);
00568       }
00569    else if(type == CLIENT_KEX)
00570       {
00571       if(state.received_handshake_msg(CERTIFICATE) && !state.client_certs()->empty())
00572          state.set_expected_next(CERTIFICATE_VERIFY);
00573       else
00574          state.set_expected_next(HANDSHAKE_CCS);
00575 
00576       state.client_kex(
00577          new Client_Key_Exchange(contents, state,
00578                                  state.server_rsa_kex_key,
00579                                  m_creds, m_policy, rng())
00580          );
00581 
00582       state.compute_session_keys();
00583       }
00584    else if(type == CERTIFICATE_VERIFY)
00585       {
00586       state.client_verify(new Certificate_Verify(contents, state.version()));
00587 
00588       const std::vector<X509_Certificate>& client_certs =
00589          state.client_certs()->cert_chain();
00590 
00591       const bool sig_valid =
00592          state.client_verify()->verify(client_certs[0], state);
00593 
00594       state.hash().update(state.handshake_io().format(contents, type));
00595 
00596       /*
00597       * Using DECRYPT_ERROR looks weird here, but per RFC 4346 is for
00598       * "A handshake cryptographic operation failed, including being
00599       * unable to correctly verify a signature, ..."
00600       */
00601       if(!sig_valid)
00602          throw TLS_Exception(Alert::DECRYPT_ERROR, "Client cert verify failed");
00603 
00604       try
00605          {
00606          m_creds.verify_certificate_chain("tls-server", "", client_certs);
00607          }
00608       catch(std::exception& e)
00609          {
00610          throw TLS_Exception(Alert::BAD_CERTIFICATE, e.what());
00611          }
00612 
00613       state.set_expected_next(HANDSHAKE_CCS);
00614       }
00615    else if(type == HANDSHAKE_CCS)
00616       {
00617       if(state.server_hello()->next_protocol_notification())
00618          state.set_expected_next(NEXT_PROTOCOL);
00619       else
00620          state.set_expected_next(FINISHED);
00621 
00622       change_cipher_spec_reader(SERVER);
00623       }
00624    else if(type == NEXT_PROTOCOL)
00625       {
00626       state.set_expected_next(FINISHED);
00627 
00628       state.next_protocol(new Next_Protocol(contents));
00629 
00630       // should this be a callback?
00631       m_next_protocol = state.next_protocol()->protocol();
00632       }
00633    else if(type == FINISHED)
00634       {
00635       state.set_expected_next(HANDSHAKE_NONE);
00636 
00637       state.client_finished(new Finished(contents));
00638 
00639       if(!state.client_finished()->verify(state, CLIENT))
00640          throw TLS_Exception(Alert::DECRYPT_ERROR,
00641                              "Finished message didn't verify");
00642 
00643       if(!state.server_finished())
00644          {
00645          // already sent finished if resuming, so this is a new session
00646 
00647          state.hash().update(state.handshake_io().format(contents, type));
00648 
00649          Session session_info(
00650             state.server_hello()->session_id(),
00651             state.session_keys().master_secret(),
00652             state.server_hello()->version(),
00653             state.server_hello()->ciphersuite(),
00654             state.server_hello()->compression_method(),
00655             SERVER,
00656             state.server_hello()->fragment_size(),
00657             get_peer_cert_chain(state),
00658             std::vector<byte>(),
00659             Server_Information(state.client_hello()->sni_hostname()),
00660             state.srp_identifier(),
00661             state.server_hello()->srtp_profile()
00662             );
00663 
00664          if(save_session(session_info))
00665             {
00666             if(state.server_hello()->supports_session_ticket())
00667                {
00668                try
00669                   {
00670                   const SymmetricKey ticket_key = m_creds.psk("tls-server", "session-ticket", "");
00671 
00672                   state.new_session_ticket(
00673                      new New_Session_Ticket(state.handshake_io(),
00674                                             state.hash(),
00675                                             session_info.encrypt(ticket_key, rng()),
00676                                             m_policy.session_ticket_lifetime())
00677                      );
00678                   }
00679                catch(...) {}
00680                }
00681             else
00682                session_manager().save(session_info);
00683             }
00684 
00685          if(!state.new_session_ticket() &&
00686             state.server_hello()->supports_session_ticket())
00687             {
00688             state.new_session_ticket(
00689                new New_Session_Ticket(state.handshake_io(), state.hash())
00690                );
00691             }
00692 
00693          state.handshake_io().send(Change_Cipher_Spec());
00694 
00695          change_cipher_spec_writer(SERVER);
00696 
00697          state.server_finished(
00698             new Finished(state.handshake_io(), state, SERVER)
00699             );
00700          }
00701 
00702       activate_session();
00703       }
00704    else
00705       throw Unexpected_Message("Unknown handshake message received");
00706    }
00707 
00708 }
00709 
00710 }