Serenity Operating System
at master 415 lines 18 kB view raw
1/* 2 * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org> 3 * Copyright (c) 2022, Michiel Visser <opensource@webmichiel.nl> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#include <AK/Debug.h> 9#include <AK/Endian.h> 10#include <AK/Random.h> 11 12#include <LibCore/Timer.h> 13#include <LibCrypto/ASN1/DER.h> 14#include <LibCrypto/Curves/EllipticCurve.h> 15#include <LibCrypto/Curves/SECP256r1.h> 16#include <LibCrypto/Curves/X25519.h> 17#include <LibCrypto/Curves/X448.h> 18#include <LibCrypto/PK/Code/EMSA_PKCS1_V1_5.h> 19#include <LibCrypto/PK/Code/EMSA_PSS.h> 20#include <LibTLS/TLSv12.h> 21 22namespace TLS { 23 24ssize_t TLSv12::handle_server_hello(ReadonlyBytes buffer, WritePacketStage& write_packets) 25{ 26 write_packets = WritePacketStage::Initial; 27 if (m_context.connection_status != ConnectionStatus::Disconnected && m_context.connection_status != ConnectionStatus::Renegotiating) { 28 dbgln("unexpected hello message"); 29 return (i8)Error::UnexpectedMessage; 30 } 31 ssize_t res = 0; 32 size_t min_hello_size = 41; 33 34 if (min_hello_size > buffer.size()) { 35 dbgln("need more data"); 36 return (i8)Error::NeedMoreData; 37 } 38 size_t following_bytes = buffer[0] * 0x10000 + buffer[1] * 0x100 + buffer[2]; 39 res += 3; 40 if (buffer.size() - res < following_bytes) { 41 dbgln("not enough data after header: {} < {}", buffer.size() - res, following_bytes); 42 return (i8)Error::NeedMoreData; 43 } 44 45 if (buffer.size() - res < 2) { 46 dbgln("not enough data for version"); 47 return (i8)Error::NeedMoreData; 48 } 49 auto version = static_cast<Version>(AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res)))); 50 51 res += 2; 52 if (!supports_version(version)) 53 return (i8)Error::NotSafe; 54 55 memcpy(m_context.remote_random, buffer.offset_pointer(res), sizeof(m_context.remote_random)); 56 res += sizeof(m_context.remote_random); 57 58 u8 session_length = buffer[res++]; 59 if (buffer.size() - res < session_length) { 60 dbgln("not enough data for session id"); 61 return (i8)Error::NeedMoreData; 62 } 63 64 if (session_length && session_length <= 32) { 65 memcpy(m_context.session_id, buffer.offset_pointer(res), session_length); 66 m_context.session_id_size = session_length; 67 if constexpr (TLS_DEBUG) { 68 dbgln("Remote session ID:"); 69 print_buffer(ReadonlyBytes { m_context.session_id, session_length }); 70 } 71 } else { 72 m_context.session_id_size = 0; 73 } 74 res += session_length; 75 76 if (buffer.size() - res < 2) { 77 dbgln("not enough data for cipher suite listing"); 78 return (i8)Error::NeedMoreData; 79 } 80 auto cipher = static_cast<CipherSuite>(AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res)))); 81 res += 2; 82 if (!supports_cipher(cipher)) { 83 m_context.cipher = CipherSuite::Invalid; 84 dbgln("No supported cipher could be agreed upon"); 85 return (i8)Error::NoCommonCipher; 86 } 87 m_context.cipher = cipher; 88 dbgln_if(TLS_DEBUG, "Cipher: {}", (u16)cipher); 89 90 // Simplification: We only support handshake hash functions via HMAC 91 m_context.handshake_hash.initialize(hmac_hash()); 92 93 // Compression method 94 if (buffer.size() - res < 1) 95 return (i8)Error::NeedMoreData; 96 u8 compression = buffer[res++]; 97 if (compression != 0) 98 return (i8)Error::CompressionNotSupported; 99 100 if (m_context.connection_status != ConnectionStatus::Renegotiating) 101 m_context.connection_status = ConnectionStatus::Negotiating; 102 if (m_context.is_server) { 103 dbgln("unsupported: server mode"); 104 write_packets = WritePacketStage::ServerHandshake; 105 } 106 107 // Presence of extensions is determined by availability of bytes after compression_method 108 if (buffer.size() - res >= 2) { 109 auto extensions_bytes_total = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res += 2))); 110 dbgln_if(TLS_DEBUG, "Extensions bytes total: {}", extensions_bytes_total); 111 } 112 113 while (buffer.size() - res >= 4) { 114 auto extension_type = (HandshakeExtension)AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res))); 115 res += 2; 116 u16 extension_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res))); 117 res += 2; 118 119 dbgln_if(TLS_DEBUG, "Extension {} with length {}", (u16)extension_type, extension_length); 120 121 if (buffer.size() - res < extension_length) 122 return (i8)Error::NeedMoreData; 123 124 if (extension_type == HandshakeExtension::ServerName) { 125 // RFC6066 section 3: SNI extension_data can be empty in the server hello 126 if (extension_length > 0) { 127 // ServerNameList total size 128 if (buffer.size() - res < 2) 129 return (i8)Error::NeedMoreData; 130 auto sni_name_list_bytes = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res += 2))); 131 dbgln_if(TLS_DEBUG, "SNI: expecting ServerNameList of {} bytes", sni_name_list_bytes); 132 133 // Exactly one ServerName should be present 134 if (buffer.size() - res < 3) 135 return (i8)Error::NeedMoreData; 136 auto sni_name_type = (NameType)(*(u8 const*)buffer.offset_pointer(res++)); 137 auto sni_name_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res += 2))); 138 139 if (sni_name_type != NameType::HostName) 140 return (i8)Error::NotUnderstood; 141 142 if (sizeof(sni_name_type) + sizeof(sni_name_length) + sni_name_length != sni_name_list_bytes) 143 return (i8)Error::BrokenPacket; 144 145 // Read out the host_name 146 if (buffer.size() - res < sni_name_length) 147 return (i8)Error::NeedMoreData; 148 m_context.extensions.SNI = DeprecatedString { (char const*)buffer.offset_pointer(res), sni_name_length }; 149 res += sni_name_length; 150 dbgln("SNI host_name: {}", m_context.extensions.SNI); 151 } 152 } else if (extension_type == HandshakeExtension::ApplicationLayerProtocolNegotiation && m_context.alpn.size()) { 153 if (buffer.size() - res > 2) { 154 auto alpn_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res))); 155 if (alpn_length && alpn_length <= extension_length - 2) { 156 u8 const* alpn = buffer.offset_pointer(res + 2); 157 size_t alpn_position = 0; 158 while (alpn_position < alpn_length) { 159 u8 alpn_size = alpn[alpn_position++]; 160 if (alpn_size + alpn_position >= extension_length) 161 break; 162 DeprecatedString alpn_str { (char const*)alpn + alpn_position, alpn_length }; 163 if (alpn_size && m_context.alpn.contains_slow(alpn_str)) { 164 m_context.negotiated_alpn = alpn_str; 165 dbgln("negotiated alpn: {}", alpn_str); 166 break; 167 } 168 alpn_position += alpn_length; 169 if (!m_context.is_server) // server hello must contain one ALPN 170 break; 171 } 172 } 173 } 174 res += extension_length; 175 } else if (extension_type == HandshakeExtension::SignatureAlgorithms) { 176 dbgln("supported signatures: "); 177 print_buffer(buffer.slice(res, extension_length)); 178 res += extension_length; 179 // FIXME: what are we supposed to do here? 180 } else if (extension_type == HandshakeExtension::ECPointFormats) { 181 // RFC8422 section 5.2: A server that selects an ECC cipher suite in response to a ClientHello message 182 // including a Supported Point Formats Extension appends this extension (along with others) to its 183 // ServerHello message, enumerating the point formats it can parse. The Supported Point Formats Extension, 184 // when used, MUST contain the value 0 (uncompressed) as one of the items in the list of point formats. 185 // 186 // The current implementation only supports uncompressed points, and the server is required to support 187 // uncompressed points. Therefore, this extension can be safely ignored as it should always inform us 188 // that the server supports uncompressed points. 189 res += extension_length; 190 } else { 191 dbgln("Encountered unknown extension {} with length {}", (u16)extension_type, extension_length); 192 res += extension_length; 193 } 194 } 195 196 return res; 197} 198 199ssize_t TLSv12::handle_server_hello_done(ReadonlyBytes buffer) 200{ 201 if (buffer.size() < 3) 202 return (i8)Error::NeedMoreData; 203 204 size_t size = buffer[0] * 0x10000 + buffer[1] * 0x100 + buffer[2]; 205 206 if (buffer.size() - 3 < size) 207 return (i8)Error::NeedMoreData; 208 209 return size + 3; 210} 211 212ByteBuffer TLSv12::build_server_key_exchange() 213{ 214 dbgln("FIXME: build_server_key_exchange"); 215 return {}; 216} 217 218ssize_t TLSv12::handle_server_key_exchange(ReadonlyBytes buffer) 219{ 220 switch (get_key_exchange_algorithm(m_context.cipher)) { 221 case KeyExchangeAlgorithm::RSA: 222 case KeyExchangeAlgorithm::DH_DSS: 223 case KeyExchangeAlgorithm::DH_RSA: 224 // RFC 5246 section 7.4.3. Server Key Exchange Message 225 // It is not legal to send the server key exchange message for RSA, DH_DSS, DH_RSA 226 dbgln("Server key exchange received for RSA, DH_DSS or DH_RSA is not legal"); 227 return (i8)Error::UnexpectedMessage; 228 case KeyExchangeAlgorithm::DHE_DSS: 229 dbgln("Server key exchange for DHE_DSS is not implemented"); 230 TODO(); 231 break; 232 case KeyExchangeAlgorithm::DHE_RSA: 233 return handle_dhe_rsa_server_key_exchange(buffer); 234 case KeyExchangeAlgorithm::DH_anon: 235 dbgln("Server key exchange for DH_anon is not implemented"); 236 TODO(); 237 break; 238 case KeyExchangeAlgorithm::ECDHE_RSA: 239 return handle_ecdhe_rsa_server_key_exchange(buffer); 240 case KeyExchangeAlgorithm::ECDH_ECDSA: 241 case KeyExchangeAlgorithm::ECDH_RSA: 242 case KeyExchangeAlgorithm::ECDHE_ECDSA: 243 case KeyExchangeAlgorithm::ECDH_anon: 244 dbgln("Server key exchange for ECDHE algorithms is not implemented"); 245 TODO(); 246 break; 247 default: 248 dbgln("Unknown server key exchange algorithm"); 249 VERIFY_NOT_REACHED(); 250 break; 251 } 252 return 0; 253} 254 255ssize_t TLSv12::handle_dhe_rsa_server_key_exchange(ReadonlyBytes buffer) 256{ 257 auto dh_p_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(3))); 258 auto dh_p = buffer.slice(5, dh_p_length); 259 auto p_result = ByteBuffer::copy(dh_p); 260 if (p_result.is_error()) { 261 dbgln("dhe_rsa_server_key_exchange failed: Not enough memory"); 262 return (i8)Error::OutOfMemory; 263 } 264 m_context.server_diffie_hellman_params.p = p_result.release_value(); 265 266 auto dh_g_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(5 + dh_p_length))); 267 auto dh_g = buffer.slice(7 + dh_p_length, dh_g_length); 268 auto g_result = ByteBuffer::copy(dh_g); 269 if (g_result.is_error()) { 270 dbgln("dhe_rsa_server_key_exchange failed: Not enough memory"); 271 return (i8)Error::OutOfMemory; 272 } 273 m_context.server_diffie_hellman_params.g = g_result.release_value(); 274 275 auto dh_Ys_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(7 + dh_p_length + dh_g_length))); 276 auto dh_Ys = buffer.slice(9 + dh_p_length + dh_g_length, dh_Ys_length); 277 auto Ys_result = ByteBuffer::copy(dh_Ys); 278 if (Ys_result.is_error()) { 279 dbgln("dhe_rsa_server_key_exchange failed: Not enough memory"); 280 return (i8)Error::OutOfMemory; 281 } 282 m_context.server_diffie_hellman_params.Ys = Ys_result.release_value(); 283 284 if constexpr (TLS_DEBUG) { 285 dbgln("dh_p: {:hex-dump}", dh_p); 286 dbgln("dh_g: {:hex-dump}", dh_g); 287 dbgln("dh_Ys: {:hex-dump}", dh_Ys); 288 } 289 290 auto server_key_info = buffer.slice(3, 6 + dh_p_length + dh_g_length + dh_Ys_length); 291 auto signature = buffer.slice(9 + dh_p_length + dh_g_length + dh_Ys_length); 292 return verify_rsa_server_key_exchange(server_key_info, signature); 293} 294 295ssize_t TLSv12::handle_ecdhe_rsa_server_key_exchange(ReadonlyBytes buffer) 296{ 297 if (buffer.size() < 7) 298 return (i8)Error::NeedMoreData; 299 300 auto curve_type = buffer[3]; 301 if (curve_type != (u8)ECCurveType::NamedCurve) 302 return (i8)Error::NotUnderstood; 303 304 auto curve = static_cast<NamedCurve>(AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(4)))); 305 if (!m_context.options.elliptic_curves.contains_slow(curve)) 306 return (i8)Error::NotUnderstood; 307 308 switch ((NamedCurve)curve) { 309 case NamedCurve::x25519: 310 m_context.server_key_exchange_curve = make<Crypto::Curves::X25519>(); 311 break; 312 case NamedCurve::x448: 313 m_context.server_key_exchange_curve = make<Crypto::Curves::X448>(); 314 break; 315 case NamedCurve::secp256r1: 316 m_context.server_key_exchange_curve = make<Crypto::Curves::SECP256r1>(); 317 break; 318 default: 319 return (i8)Error::NotUnderstood; 320 } 321 322 auto server_public_key_length = buffer[6]; 323 if (server_public_key_length != m_context.server_key_exchange_curve->key_size()) 324 return (i8)Error::NotUnderstood; 325 326 if (buffer.size() < 7u + server_public_key_length) 327 return (i8)Error::NeedMoreData; 328 329 auto server_public_key = buffer.slice(7, server_public_key_length); 330 auto server_public_key_copy_result = ByteBuffer::copy(server_public_key); 331 if (server_public_key_copy_result.is_error()) { 332 dbgln("ecdhe_rsa_server_key_exchange failed: Not enough memory"); 333 return (i8)Error::OutOfMemory; 334 } 335 m_context.server_diffie_hellman_params.p = server_public_key_copy_result.release_value(); 336 337 if constexpr (TLS_DEBUG) { 338 dbgln("ECDHE server public key: {:hex-dump}", server_public_key); 339 } 340 341 auto server_key_info = buffer.slice(3, 4 + server_public_key_length); 342 auto signature = buffer.slice(7 + server_public_key_length); 343 return verify_rsa_server_key_exchange(server_key_info, signature); 344} 345 346ssize_t TLSv12::verify_rsa_server_key_exchange(ReadonlyBytes server_key_info_buffer, ReadonlyBytes signature_buffer) 347{ 348 auto signature_hash = signature_buffer[0]; 349 auto signature_algorithm = signature_buffer[1]; 350 if (signature_algorithm != (u8)SignatureAlgorithm::RSA) { 351 dbgln("verify_rsa_server_key_exchange failed: Signature algorithm is not RSA, instead {}", signature_algorithm); 352 return (i8)Error::NotUnderstood; 353 } 354 355 auto signature_length = AK::convert_between_host_and_network_endian(ByteReader::load16(signature_buffer.offset_pointer(2))); 356 auto signature = signature_buffer.slice(4, signature_length); 357 358 if (m_context.certificates.is_empty()) { 359 dbgln("verify_rsa_server_key_exchange failed: Attempting to verify signature without certificates"); 360 return (i8)Error::NotSafe; 361 } 362 // RFC5246 section 7.4.2: The sender's certificate MUST come first in the list. 363 auto certificate_public_key = m_context.certificates.first().public_key; 364 Crypto::PK::RSAPrivateKey dummy_private_key; 365 auto rsa = Crypto::PK::RSA(certificate_public_key, dummy_private_key); 366 367 auto signature_verify_buffer_result = ByteBuffer::create_uninitialized(signature_length); 368 if (signature_verify_buffer_result.is_error()) { 369 dbgln("verify_rsa_server_key_exchange failed: Not enough memory"); 370 return (i8)Error::OutOfMemory; 371 } 372 auto signature_verify_buffer = signature_verify_buffer_result.release_value(); 373 auto signature_verify_bytes = signature_verify_buffer.bytes(); 374 rsa.verify(signature, signature_verify_bytes); 375 376 auto message_result = ByteBuffer::create_uninitialized(64 + server_key_info_buffer.size()); 377 if (message_result.is_error()) { 378 dbgln("verify_rsa_server_key_exchange failed: Not enough memory"); 379 return (i8)Error::OutOfMemory; 380 } 381 auto message = message_result.release_value(); 382 message.overwrite(0, m_context.local_random, 32); 383 message.overwrite(32, m_context.remote_random, 32); 384 message.overwrite(64, server_key_info_buffer.data(), server_key_info_buffer.size()); 385 386 Crypto::Hash::HashKind hash_kind; 387 switch ((HashAlgorithm)signature_hash) { 388 case HashAlgorithm::SHA1: 389 hash_kind = Crypto::Hash::HashKind::SHA1; 390 break; 391 case HashAlgorithm::SHA256: 392 hash_kind = Crypto::Hash::HashKind::SHA256; 393 break; 394 case HashAlgorithm::SHA384: 395 hash_kind = Crypto::Hash::HashKind::SHA384; 396 break; 397 case HashAlgorithm::SHA512: 398 hash_kind = Crypto::Hash::HashKind::SHA512; 399 break; 400 default: 401 dbgln("verify_rsa_server_key_exchange failed: Hash algorithm is not SHA1/256/384/512, instead {}", signature_hash); 402 return (i8)Error::NotUnderstood; 403 } 404 405 auto pkcs1 = Crypto::PK::EMSA_PKCS1_V1_5<Crypto::Hash::Manager>(hash_kind); 406 auto verification = pkcs1.verify(message, signature_verify_bytes, signature_length * 8); 407 408 if (verification == Crypto::VerificationConsistency::Inconsistent) { 409 dbgln("verify_rsa_server_key_exchange failed: Verification of signature inconsistent"); 410 return (i8)Error::NotSafe; 411 } 412 413 return 0; 414} 415}