HandshakeServer.cpp 11 KB

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