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