HandshakeServer.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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. #include <AK/Debug.h>
  8. #include <AK/Endian.h>
  9. #include <AK/Random.h>
  10. #include <LibCore/Timer.h>
  11. #include <LibCrypto/ASN1/DER.h>
  12. #include <LibCrypto/PK/Code/EMSA_PSS.h>
  13. #include <LibTLS/TLSv12.h>
  14. namespace TLS {
  15. ssize_t TLSv12::handle_server_hello(ReadonlyBytes buffer, WritePacketStage& write_packets)
  16. {
  17. write_packets = WritePacketStage::Initial;
  18. if (m_context.connection_status != ConnectionStatus::Disconnected && m_context.connection_status != ConnectionStatus::Renegotiating) {
  19. dbgln("unexpected hello message");
  20. return (i8)Error::UnexpectedMessage;
  21. }
  22. ssize_t res = 0;
  23. size_t min_hello_size = 41;
  24. if (min_hello_size > buffer.size()) {
  25. dbgln("need more data");
  26. return (i8)Error::NeedMoreData;
  27. }
  28. size_t following_bytes = buffer[0] * 0x10000 + buffer[1] * 0x100 + buffer[2];
  29. res += 3;
  30. if (buffer.size() - res < following_bytes) {
  31. dbgln("not enough data after header: {} < {}", buffer.size() - res, following_bytes);
  32. return (i8)Error::NeedMoreData;
  33. }
  34. if (buffer.size() - res < 2) {
  35. dbgln("not enough data for version");
  36. return (i8)Error::NeedMoreData;
  37. }
  38. auto version = static_cast<Version>(AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res))));
  39. res += 2;
  40. if (!supports_version(version))
  41. return (i8)Error::NotSafe;
  42. memcpy(m_context.remote_random, buffer.offset_pointer(res), sizeof(m_context.remote_random));
  43. res += sizeof(m_context.remote_random);
  44. u8 session_length = buffer[res++];
  45. if (buffer.size() - res < session_length) {
  46. dbgln("not enough data for session id");
  47. return (i8)Error::NeedMoreData;
  48. }
  49. if (session_length && session_length <= 32) {
  50. memcpy(m_context.session_id, buffer.offset_pointer(res), session_length);
  51. m_context.session_id_size = session_length;
  52. if constexpr (TLS_DEBUG) {
  53. dbgln("Remote session ID:");
  54. print_buffer(ReadonlyBytes { m_context.session_id, session_length });
  55. }
  56. } else {
  57. m_context.session_id_size = 0;
  58. }
  59. res += session_length;
  60. if (buffer.size() - res < 2) {
  61. dbgln("not enough data for cipher suite listing");
  62. return (i8)Error::NeedMoreData;
  63. }
  64. auto cipher = static_cast<CipherSuite>(AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res))));
  65. res += 2;
  66. if (!supports_cipher(cipher)) {
  67. m_context.cipher = CipherSuite::Invalid;
  68. dbgln("No supported cipher could be agreed upon");
  69. return (i8)Error::NoCommonCipher;
  70. }
  71. m_context.cipher = cipher;
  72. dbgln_if(TLS_DEBUG, "Cipher: {}", (u16)cipher);
  73. // Simplification: We only support handshake hash functions via HMAC
  74. m_context.handshake_hash.initialize(hmac_hash());
  75. // Compression method
  76. if (buffer.size() - res < 1)
  77. return (i8)Error::NeedMoreData;
  78. u8 compression = buffer[res++];
  79. if (compression != 0)
  80. return (i8)Error::CompressionNotSupported;
  81. if (m_context.connection_status != ConnectionStatus::Renegotiating)
  82. m_context.connection_status = ConnectionStatus::Negotiating;
  83. if (m_context.is_server) {
  84. dbgln("unsupported: server mode");
  85. write_packets = WritePacketStage::ServerHandshake;
  86. }
  87. // Presence of extensions is determined by availability of bytes after compression_method
  88. if (buffer.size() - res >= 2) {
  89. auto extensions_bytes_total = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res += 2)));
  90. dbgln_if(TLS_DEBUG, "Extensions bytes total: {}", extensions_bytes_total);
  91. }
  92. while (buffer.size() - res >= 4) {
  93. auto extension_type = (HandshakeExtension)AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res)));
  94. res += 2;
  95. u16 extension_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res)));
  96. res += 2;
  97. dbgln_if(TLS_DEBUG, "Extension {} with length {}", (u16)extension_type, extension_length);
  98. if (buffer.size() - res < extension_length)
  99. return (i8)Error::NeedMoreData;
  100. if (extension_type == HandshakeExtension::ServerName) {
  101. // RFC6066 section 3: SNI extension_data can be empty in the server hello
  102. if (extension_length > 0) {
  103. // ServerNameList total size
  104. if (buffer.size() - res < 2)
  105. return (i8)Error::NeedMoreData;
  106. auto sni_name_list_bytes = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res += 2)));
  107. dbgln_if(TLS_DEBUG, "SNI: expecting ServerNameList of {} bytes", sni_name_list_bytes);
  108. // Exactly one ServerName should be present
  109. if (buffer.size() - res < 3)
  110. return (i8)Error::NeedMoreData;
  111. auto sni_name_type = (NameType)(*(const u8*)buffer.offset_pointer(res++));
  112. auto sni_name_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res += 2)));
  113. if (sni_name_type != NameType::HostName)
  114. return (i8)Error::NotUnderstood;
  115. if (sizeof(sni_name_type) + sizeof(sni_name_length) + sni_name_length != sni_name_list_bytes)
  116. return (i8)Error::BrokenPacket;
  117. // Read out the host_name
  118. if (buffer.size() - res < sni_name_length)
  119. return (i8)Error::NeedMoreData;
  120. m_context.extensions.SNI = String { (const char*)buffer.offset_pointer(res), sni_name_length };
  121. res += sni_name_length;
  122. dbgln("SNI host_name: {}", m_context.extensions.SNI);
  123. }
  124. } else if (extension_type == HandshakeExtension::ApplicationLayerProtocolNegotiation && m_context.alpn.size()) {
  125. if (buffer.size() - res > 2) {
  126. auto alpn_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res)));
  127. if (alpn_length && alpn_length <= extension_length - 2) {
  128. const u8* alpn = buffer.offset_pointer(res + 2);
  129. size_t alpn_position = 0;
  130. while (alpn_position < alpn_length) {
  131. u8 alpn_size = alpn[alpn_position++];
  132. if (alpn_size + alpn_position >= extension_length)
  133. break;
  134. String alpn_str { (const char*)alpn + alpn_position, alpn_length };
  135. if (alpn_size && m_context.alpn.contains_slow(alpn_str)) {
  136. m_context.negotiated_alpn = alpn_str;
  137. dbgln("negotiated alpn: {}", alpn_str);
  138. break;
  139. }
  140. alpn_position += alpn_length;
  141. if (!m_context.is_server) // server hello must contain one ALPN
  142. break;
  143. }
  144. }
  145. }
  146. res += extension_length;
  147. } else if (extension_type == HandshakeExtension::SignatureAlgorithms) {
  148. dbgln("supported signatures: ");
  149. print_buffer(buffer.slice(res, extension_length));
  150. res += extension_length;
  151. // FIXME: what are we supposed to do here?
  152. } else if (extension_type == HandshakeExtension::ECPointFormats) {
  153. // RFC8422 section 5.2: A server that selects an ECC cipher suite in response to a ClientHello message
  154. // including a Supported Point Formats Extension appends this extension (along with others) to its
  155. // ServerHello message, enumerating the point formats it can parse. The Supported Point Formats Extension,
  156. // when used, MUST contain the value 0 (uncompressed) as one of the items in the list of point formats.
  157. //
  158. // The current implementation only supports uncompressed points, and the server is required to support
  159. // uncompressed points. Therefore, this extension can be safely ignored as it should always inform us
  160. // that the server supports uncompressed points.
  161. res += extension_length;
  162. } else {
  163. dbgln("Encountered unknown extension {} with length {}", (u16)extension_type, extension_length);
  164. res += extension_length;
  165. }
  166. }
  167. return res;
  168. }
  169. ssize_t TLSv12::handle_server_hello_done(ReadonlyBytes buffer)
  170. {
  171. if (buffer.size() < 3)
  172. return (i8)Error::NeedMoreData;
  173. size_t size = buffer[0] * 0x10000 + buffer[1] * 0x100 + buffer[2];
  174. if (buffer.size() - 3 < size)
  175. return (i8)Error::NeedMoreData;
  176. return size + 3;
  177. }
  178. ByteBuffer TLSv12::build_server_key_exchange()
  179. {
  180. dbgln("FIXME: build_server_key_exchange");
  181. return {};
  182. }
  183. ssize_t TLSv12::handle_server_key_exchange(ReadonlyBytes buffer)
  184. {
  185. switch (get_key_exchange_algorithm(m_context.cipher)) {
  186. case KeyExchangeAlgorithm::RSA:
  187. case KeyExchangeAlgorithm::DH_DSS:
  188. case KeyExchangeAlgorithm::DH_RSA:
  189. // RFC 5246 section 7.4.3. Server Key Exchange Message
  190. // It is not legal to send the server key exchange message for RSA, DH_DSS, DH_RSA
  191. dbgln("Server key exchange received for RSA, DH_DSS or DH_RSA is not legal");
  192. return (i8)Error::UnexpectedMessage;
  193. case KeyExchangeAlgorithm::DHE_DSS:
  194. dbgln("Server key exchange for DHE_DSS is not implemented");
  195. TODO();
  196. break;
  197. case KeyExchangeAlgorithm::DHE_RSA:
  198. return handle_dhe_rsa_server_key_exchange(buffer);
  199. case KeyExchangeAlgorithm::DH_anon:
  200. dbgln("Server key exchange for DH_anon is not implemented");
  201. TODO();
  202. break;
  203. case KeyExchangeAlgorithm::ECDHE_RSA:
  204. return handle_ecdhe_rsa_server_key_exchange(buffer);
  205. case KeyExchangeAlgorithm::ECDH_ECDSA:
  206. case KeyExchangeAlgorithm::ECDH_RSA:
  207. case KeyExchangeAlgorithm::ECDHE_ECDSA:
  208. case KeyExchangeAlgorithm::ECDH_anon:
  209. dbgln("Server key exchange for ECDHE algorithms is not implemented");
  210. TODO();
  211. break;
  212. default:
  213. dbgln("Unknown server key exchange algorithm");
  214. VERIFY_NOT_REACHED();
  215. break;
  216. }
  217. return 0;
  218. }
  219. ssize_t TLSv12::handle_dhe_rsa_server_key_exchange(ReadonlyBytes buffer)
  220. {
  221. auto dh_p_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(3)));
  222. auto dh_p = buffer.slice(5, dh_p_length);
  223. auto p_result = ByteBuffer::copy(dh_p);
  224. if (p_result.is_error()) {
  225. dbgln("dhe_rsa_server_key_exchange failed: Not enough memory");
  226. return (i8)Error::OutOfMemory;
  227. }
  228. m_context.server_diffie_hellman_params.p = p_result.release_value();
  229. auto dh_g_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(5 + dh_p_length)));
  230. auto dh_g = buffer.slice(7 + dh_p_length, dh_g_length);
  231. auto g_result = ByteBuffer::copy(dh_g);
  232. if (g_result.is_error()) {
  233. dbgln("dhe_rsa_server_key_exchange failed: Not enough memory");
  234. return (i8)Error::OutOfMemory;
  235. }
  236. m_context.server_diffie_hellman_params.g = g_result.release_value();
  237. auto dh_Ys_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(7 + dh_p_length + dh_g_length)));
  238. auto dh_Ys = buffer.slice(9 + dh_p_length + dh_g_length, dh_Ys_length);
  239. auto Ys_result = ByteBuffer::copy(dh_Ys);
  240. if (Ys_result.is_error()) {
  241. dbgln("dhe_rsa_server_key_exchange failed: Not enough memory");
  242. return (i8)Error::OutOfMemory;
  243. }
  244. m_context.server_diffie_hellman_params.Ys = Ys_result.release_value();
  245. if constexpr (TLS_DEBUG) {
  246. dbgln("dh_p: {:hex-dump}", dh_p);
  247. dbgln("dh_g: {:hex-dump}", dh_g);
  248. dbgln("dh_Ys: {:hex-dump}", dh_Ys);
  249. }
  250. // FIXME: Validate signature of Diffie-Hellman parameters as defined in RFC 5246 section 7.4.3.
  251. return 0;
  252. }
  253. ssize_t TLSv12::handle_ecdhe_rsa_server_key_exchange(ReadonlyBytes buffer)
  254. {
  255. auto x25519_key_size_bytes = named_curve_key_size(NamedCurve::x25519) / 8;
  256. if (buffer.size() < x25519_key_size_bytes + 7)
  257. return (i8)Error::NeedMoreData;
  258. auto curve_type = buffer[3];
  259. if (curve_type != (u8)ECCurveType::NamedCurve)
  260. return (i8)Error::FeatureNotSupported;
  261. auto curve = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(4)));
  262. if (curve != (u16)NamedCurve::x25519)
  263. return (i8)Error::FeatureNotSupported;
  264. auto server_public_key_length = buffer[6];
  265. if (server_public_key_length != x25519_key_size_bytes)
  266. return (i8)Error::FeatureNotSupported;
  267. auto server_public_key = buffer.slice(7, server_public_key_length);
  268. auto server_public_key_copy_result = ByteBuffer::copy(server_public_key);
  269. if (server_public_key_copy_result.is_error()) {
  270. dbgln("ecdhe_rsa_server_key_exchange failed: Not enough memory");
  271. return (i8)Error::OutOfMemory;
  272. }
  273. m_context.server_diffie_hellman_params.p = server_public_key_copy_result.release_value();
  274. if constexpr (TLS_DEBUG) {
  275. dbgln("ECDHE server public key: {:hex-dump}", server_public_key);
  276. }
  277. // FIXME: Validate signature of Elliptic Curve Diffie-Hellman public key
  278. return 0;
  279. }
  280. }