Botan
1.11.15
|
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 }