Botan
1.11.15
|
00001 /* 00002 * Server Key Exchange Message 00003 * (C) 2004-2010,2012 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/loadstor.h> 00014 #include <botan/pubkey.h> 00015 #include <botan/dh.h> 00016 #include <botan/ecdh.h> 00017 #include <botan/rsa.h> 00018 #include <botan/srp6.h> 00019 #include <botan/oids.h> 00020 00021 namespace Botan { 00022 00023 namespace TLS { 00024 00025 /** 00026 * Create a new Server Key Exchange message 00027 */ 00028 Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, 00029 Handshake_State& state, 00030 const Policy& policy, 00031 Credentials_Manager& creds, 00032 RandomNumberGenerator& rng, 00033 const Private_Key* signing_key) 00034 { 00035 const std::string hostname = state.client_hello()->sni_hostname(); 00036 const std::string kex_algo = state.ciphersuite().kex_algo(); 00037 00038 if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 00039 { 00040 std::string identity_hint = 00041 creds.psk_identity_hint("tls-server", hostname); 00042 00043 append_tls_length_value(m_params, identity_hint, 2); 00044 } 00045 00046 if(kex_algo == "DH" || kex_algo == "DHE_PSK") 00047 { 00048 std::unique_ptr<DH_PrivateKey> dh(new DH_PrivateKey(rng, policy.dh_group())); 00049 00050 append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_p()), 2); 00051 append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_g()), 2); 00052 append_tls_length_value(m_params, dh->public_value(), 2); 00053 m_kex_key.reset(dh.release()); 00054 } 00055 else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") 00056 { 00057 const std::vector<std::string>& curves = 00058 state.client_hello()->supported_ecc_curves(); 00059 00060 if(curves.empty()) 00061 throw Internal_Error("Client sent no ECC extension but we negotiated ECDH"); 00062 00063 const std::string curve_name = policy.choose_curve(curves); 00064 00065 if(curve_name == "") 00066 throw TLS_Exception(Alert::HANDSHAKE_FAILURE, 00067 "Could not agree on an ECC curve with the client"); 00068 00069 EC_Group ec_group(curve_name); 00070 00071 std::unique_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group)); 00072 00073 const std::string ecdh_domain_oid = ecdh->domain().get_oid(); 00074 const std::string domain = OIDS::lookup(OID(ecdh_domain_oid)); 00075 00076 if(domain == "") 00077 throw Internal_Error("Could not find name of ECDH domain " + ecdh_domain_oid); 00078 00079 const u16bit named_curve_id = Supported_Elliptic_Curves::name_to_curve_id(domain); 00080 00081 m_params.push_back(3); // named curve 00082 m_params.push_back(get_byte(0, named_curve_id)); 00083 m_params.push_back(get_byte(1, named_curve_id)); 00084 00085 append_tls_length_value(m_params, ecdh->public_value(), 1); 00086 00087 m_kex_key.reset(ecdh.release()); 00088 } 00089 else if(kex_algo == "SRP_SHA") 00090 { 00091 const std::string srp_identifier = state.client_hello()->srp_identifier(); 00092 00093 std::string group_id; 00094 BigInt v; 00095 std::vector<byte> salt; 00096 00097 const bool found = creds.srp_verifier("tls-server", hostname, 00098 srp_identifier, 00099 group_id, v, salt, 00100 policy.hide_unknown_users()); 00101 00102 if(!found) 00103 throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY, 00104 "Unknown SRP user " + srp_identifier); 00105 00106 m_srp_params.reset(new SRP6_Server_Session); 00107 00108 BigInt B = m_srp_params->step1(v, group_id, 00109 "SHA-1", rng); 00110 00111 DL_Group group(group_id); 00112 00113 append_tls_length_value(m_params, BigInt::encode(group.get_p()), 2); 00114 append_tls_length_value(m_params, BigInt::encode(group.get_g()), 2); 00115 append_tls_length_value(m_params, salt, 1); 00116 append_tls_length_value(m_params, BigInt::encode(B), 2); 00117 } 00118 else if(kex_algo != "PSK") 00119 throw Internal_Error("Server_Key_Exchange: Unknown kex type " + kex_algo); 00120 00121 if(state.ciphersuite().sig_algo() != "") 00122 { 00123 BOTAN_ASSERT(signing_key, "Signing key was set"); 00124 00125 std::pair<std::string, Signature_Format> format = 00126 state.choose_sig_format(*signing_key, m_hash_algo, m_sig_algo, false, policy); 00127 00128 PK_Signer signer(*signing_key, format.first, format.second); 00129 00130 signer.update(state.client_hello()->random()); 00131 signer.update(state.server_hello()->random()); 00132 signer.update(params()); 00133 m_signature = signer.signature(rng); 00134 } 00135 00136 state.hash().update(io.send(*this)); 00137 } 00138 00139 /** 00140 * Deserialize a Server Key Exchange message 00141 */ 00142 Server_Key_Exchange::Server_Key_Exchange(const std::vector<byte>& buf, 00143 const std::string& kex_algo, 00144 const std::string& sig_algo, 00145 Protocol_Version version) : 00146 m_kex_key(nullptr), m_srp_params(nullptr) 00147 { 00148 if(buf.size() < 6) 00149 throw Decoding_Error("Server_Key_Exchange: Packet corrupted"); 00150 00151 TLS_Data_Reader reader("ServerKeyExchange", buf); 00152 00153 /* 00154 * We really are just serializing things back to what they were 00155 * before, but unfortunately to know where the signature is we need 00156 * to be able to parse the whole thing anyway. 00157 */ 00158 00159 if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 00160 { 00161 const std::string identity_hint = reader.get_string(2, 0, 65535); 00162 append_tls_length_value(m_params, identity_hint, 2); 00163 } 00164 00165 if(kex_algo == "DH" || kex_algo == "DHE_PSK") 00166 { 00167 // 3 bigints, DH p, g, Y 00168 00169 for(size_t i = 0; i != 3; ++i) 00170 { 00171 BigInt v = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); 00172 append_tls_length_value(m_params, BigInt::encode(v), 2); 00173 } 00174 } 00175 else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") 00176 { 00177 const byte curve_type = reader.get_byte(); 00178 00179 if(curve_type != 3) 00180 throw Decoding_Error("Server_Key_Exchange: Server sent non-named ECC curve"); 00181 00182 const u16bit curve_id = reader.get_u16bit(); 00183 00184 const std::string name = Supported_Elliptic_Curves::curve_id_to_name(curve_id); 00185 00186 std::vector<byte> ecdh_key = reader.get_range<byte>(1, 1, 255); 00187 00188 if(name == "") 00189 throw Decoding_Error("Server_Key_Exchange: Server sent unknown named curve " + 00190 std::to_string(curve_id)); 00191 00192 m_params.push_back(curve_type); 00193 m_params.push_back(get_byte(0, curve_id)); 00194 m_params.push_back(get_byte(1, curve_id)); 00195 append_tls_length_value(m_params, ecdh_key, 1); 00196 } 00197 else if(kex_algo == "SRP_SHA") 00198 { 00199 // 2 bigints (N,g) then salt, then server B 00200 00201 const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); 00202 const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); 00203 std::vector<byte> salt = reader.get_range<byte>(1, 1, 255); 00204 const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); 00205 00206 append_tls_length_value(m_params, BigInt::encode(N), 2); 00207 append_tls_length_value(m_params, BigInt::encode(g), 2); 00208 append_tls_length_value(m_params, salt, 1); 00209 append_tls_length_value(m_params, BigInt::encode(B), 2); 00210 } 00211 else if(kex_algo != "PSK") 00212 throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + kex_algo); 00213 00214 if(sig_algo != "") 00215 { 00216 if(version.supports_negotiable_signature_algorithms()) 00217 { 00218 m_hash_algo = Signature_Algorithms::hash_algo_name(reader.get_byte()); 00219 m_sig_algo = Signature_Algorithms::sig_algo_name(reader.get_byte()); 00220 } 00221 00222 m_signature = reader.get_range<byte>(2, 0, 65535); 00223 } 00224 00225 reader.assert_done(); 00226 } 00227 00228 Server_Key_Exchange::~Server_Key_Exchange() {} 00229 00230 /** 00231 * Serialize a Server Key Exchange message 00232 */ 00233 std::vector<byte> Server_Key_Exchange::serialize() const 00234 { 00235 std::vector<byte> buf = params(); 00236 00237 if(m_signature.size()) 00238 { 00239 // This should be an explicit version check 00240 if(m_hash_algo != "" && m_sig_algo != "") 00241 { 00242 buf.push_back(Signature_Algorithms::hash_algo_code(m_hash_algo)); 00243 buf.push_back(Signature_Algorithms::sig_algo_code(m_sig_algo)); 00244 } 00245 00246 append_tls_length_value(buf, m_signature, 2); 00247 } 00248 00249 return buf; 00250 } 00251 00252 /** 00253 * Verify a Server Key Exchange message 00254 */ 00255 bool Server_Key_Exchange::verify(const Public_Key& server_key, 00256 const Handshake_State& state) const 00257 { 00258 std::pair<std::string, Signature_Format> format = 00259 state.understand_sig_format(server_key, m_hash_algo, m_sig_algo); 00260 00261 PK_Verifier verifier(server_key, format.first, format.second); 00262 00263 verifier.update(state.client_hello()->random()); 00264 verifier.update(state.server_hello()->random()); 00265 verifier.update(params()); 00266 00267 return verifier.check_signature(m_signature); 00268 } 00269 00270 const Private_Key& Server_Key_Exchange::server_kex_key() const 00271 { 00272 BOTAN_ASSERT_NONNULL(m_kex_key); 00273 return *m_kex_key; 00274 } 00275 00276 // Only valid for SRP negotiation 00277 SRP6_Server_Session& Server_Key_Exchange::server_srp_params() const 00278 { 00279 BOTAN_ASSERT_NONNULL(m_srp_params); 00280 return *m_srp_params; 00281 } 00282 } 00283 00284 }